Dang_Quan_10_Tin

TASKSELECT ( Đề thi) Dp Aproach

Nov 24th, 2020 (edited)
331
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.12 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define task "TASKSELECT"
  3. using namespace std;
  4. #define ll long long
  5. #define ld long double
  6. #define ull unsigned long long
  7.  
  8. const int N = 1e5 + 2;
  9. const ll mod = 1e9 + 7;
  10. int a[] = {0, 1, 2, 3, 4, 5};
  11. string n;
  12. int m;
  13. ll dp[12][6][150];
  14. int k;
  15.  
  16. void Read()
  17. {
  18.     cin >> n >> k;
  19. }
  20.  
  21. /// dp(i, j, k) là xét đến chữ số thứ i của n, số thứ j trong 4 số và còn đang nhớ k đơn vị
  22. /// dp(i, j, k) = dp(i - 1, 4, v) + dp(i, 1, v') + dp(i, 2, v") + dp(i, 3, v"') + dp(i, 4, v"") với mọi bộ số v / 10 + v' + v" + v"' + v"" = k
  23. /// Cho dễ thì đặt dp(i, 0, z) = dp(i - 1, 4, v)
  24. /// Cơ sở dp(0, 0, 0) = 1
  25. /// Đáp án là dp(m + 1, 0, 0) hay dp(m, 4, n[m] - '0')
  26.  
  27. ll Cal(string n, int k, vector<int> a)
  28. {
  29.     int m;
  30.     reverse(n.begin(), n.end());
  31.     m = n.size() - 1;
  32.     memset(dp, 0, sizeof dp);
  33.     dp[0][0][0] = 1;
  34.     for (int i = 0; i <= m; ++i)
  35.     {
  36.         for (int j = 1; j <= k; ++j)
  37.             for (int t = 0; t < 150; ++t)
  38.                 for (int h = 0; h < 10; ++h)
  39.                     if (h * a[j] <= t)
  40.                         dp[i][j][t] = (dp[i][j][t] + dp[i][j - 1][t - a[j] * h]) % mod;
  41.         for (int j = 0; j < 150; ++j)
  42.             if (j % 10 == n[i] - '0')
  43.                 dp[i + 1][0][j / 10] = (dp[i + 1][0][j / 10] + dp[i][k][j]) % mod;
  44.     }
  45.     return dp[m + 1][0][0];
  46. }
  47.  
  48. void Solve()
  49. {
  50.     ll ans = 0;
  51.     for (int i = 1; i < (1 << k); ++i)
  52.     {
  53.         vector<int> f({0});
  54.         for (int j = 0; j < k; ++j)
  55.             if ((i >> j) & 1)
  56.                 f.push_back(a[j + 1]);
  57.         if ((__builtin_popcount(i) & 1) == (k & 1))
  58.             (ans += Cal(n, __builtin_popcount(i), f)) %= mod;
  59.         else
  60.             (ans -= Cal(n, __builtin_popcount(i), f)) %= mod;
  61.     }
  62.     cout << (ans + mod) % mod;
  63. }
  64.  
  65. int32_t main()
  66. {
  67.     ios::sync_with_stdio(0);
  68.     cin.tie(0);
  69.     cout.tie(0);
  70.     if (fopen(task ".INP", "r"))
  71.         freopen(task ".INP", "r", stdin),
  72.             freopen(task ".OUT", "w", stdout);
  73.     int t;
  74.     cin >> t;
  75.     while (t--)
  76.     {
  77.         Read();
  78.         Solve();
  79.     }
  80. }
Add Comment
Please, Sign In to add comment