nrk009

DigitDP

May 19th, 2020
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.63 KB | None | 0 0
  1.  
  2.  
  3. #include<bits/stdc++.h>
  4. using namespace std;
  5.  
  6. #define fast ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL)
  7. #define ll long long
  8. #define ld long double
  9. #define pb push_back
  10. #define fe first
  11. #define se second
  12. #define nl "\n"
  13. #define pp pair < ll , ll >
  14. #define sz(x) (ll)x.size()
  15. #define st(x) sort(x.begin(),x.end())
  16. #define rst(x) sort(x.rbegin(), x.rend())
  17. #define all(x) x.begin(),x.end()
  18. long double pi = 3.14159265358979323;
  19.  
  20. const double EPS = 1e-12;
  21. const int N = 1e6 + 5;
  22. const int mod = 1e9 + 7;
  23.  
  24. //DigitDp
  25. ll a , b;
  26. ll k,d;
  27. /// How many numbers x are there in the range a to b, where the digit d occurs exactly k times in x?
  28.    
  29. ll dp[20][20][2];
  30. // DP[p][c][f] = Number of valid numbers <= b from this state
  31. /// p = current position from left side (zero based)
  32. /// c = number of times we have placed the digit d so far
  33. /// f = the number we are building has already become smaller than b? [0 = no, 1 = yes]
  34.  
  35. vector < int > num;
  36.  
  37.  
  38. ll recur(ll pos ,ll cnt,bool f){
  39.  
  40.             if(cnt > k){
  41.                 //cout << pos << " " << cnt << " " << f << "\n";
  42.                 return 0;   }
  43.             if(pos == sz(num)){
  44.                 if(cnt == k)return 1;
  45.                 return 0;    }
  46.             if(dp[pos][cnt][f] != -1)return dp[pos][cnt][f];
  47.  
  48.             ll lmt = 9;
  49.            // cout << lmt;
  50.             //cout << pos << " ";
  51.             if(f == 0){
  52.                 // Digits we placed so far matches with the prefix of b
  53. /// So if we place any digit > num[pos] in the current position, then the number will become greater than b
  54.              //  cout << num[pos]  << " ";
  55.                 lmt = num[pos];
  56.             }
  57.             //cout << lmt << " ";
  58.             ll res = 0 ;
  59.             for(int i = 0 ; i <= lmt ;i++ ){
  60.                     bool nf = f;
  61.                     ll ncnt = cnt;
  62.                     if(i < lmt)nf = 1;
  63.                     if(i == d)ncnt++;
  64.                     if(cnt <= k)res += recur(pos + 1 , ncnt , nf);
  65.             }
  66.             return dp[pos][cnt][f] = res;
  67. }
  68.  
  69. ll solve(ll n){
  70.     num.clear();
  71.     while(n){
  72.         num.pb(n%10);
  73.         n /= 10;
  74.     }  
  75.     reverse(all(num));
  76.    // cout << num[0];
  77.    // for(auto it : num)cout << it ;
  78.     memset(dp,-1,sizeof(dp));
  79.     return recur(0,0,0);
  80. }
  81. int main()
  82. {
  83.     fast;
  84.     //string a , b;
  85.     cin >> a >> b >> d >> k ;
  86.     //cout << k ;
  87.     //cout << a << " " << b ;
  88.     memset(dp , -1 , sizeof(dp));
  89.    // cout << b <<  " ";
  90.     cout << solve(b)- solve(a-1);
  91.    // cout << solve(0,0,0,b) - solve(0,0,0,a);
  92.    
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.    
  115.     return 0;
  116.    
  117. }
Add Comment
Please, Sign In to add comment