• 【数位dp】


    hdu5787

    问:L ~ R有多少个数是K-wolf Number?其中,K-wolf Number的定义是这个数在十进制下,任意相邻的K个字符没有相同的。

    dp[i][j][k]表示有i个空位可填,其中不能填j这个数字中所含有的字符,k = true(表示j有前导0)时,还不能填0.

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 #define pii pair<int, int>
     4 #define mp make_pair
     5 #define fi first
     6 #define se second
     7 using namespace std;
     8 const int N = 1e5+5;
     9 ll l, r;
    10 int k;
    11 ll dp[20][100001][2];
    12 int temp[20], tot;
    13 
    14 ll dfs(int pos, int w, bool tag, bool flag){
    15 
    16     if(!pos) return 1;
    17     if(flag&&~dp[pos][w][tag]) return dp[pos][w][tag];
    18     int Max = flag? 9: temp[pos];
    19 
    20     int ret[5], sum = 0, tmp = w;
    21     while(tmp)
    22         ret[sum++] = tmp%10, tmp /= 10;
    23     if(tag) ret[sum++] = 0;
    24 
    25     ll ans = 0;
    26     for(int i = 0; i <= Max; i++){
    27         bool tag2 = true;
    28         for(int j = 0; j < sum&&j < k-1; j++)
    29             if(ret[j] == i) tag2 = false;
    30         if(tag2){
    31             tmp = 0;
    32             int first = min(k-2, sum-1);
    33             for(int j = first; j >= 0; j--)
    34                 tmp = tmp*10+ret[j];
    35             bool tag3 = false;
    36             if(first >= 0&&ret[first] == 0) tag3 = true;
    37             ans += dfs(pos-1, tmp*10+i, tag3, flag||i != Max);
    38         }
    39     }
    40     if(flag) dp[pos][w][tag] = ans;
    41     //printf("dfs %d, %d, %d, %d %lld
    ", pos, w, tag*1, flag*1, ans);
    42     return ans;
    43 }
    44 
    45 ll solve(ll x){
    46     tot = 0;
    47     while(x){
    48         temp[++tot] = x%10;
    49         x /= 10;
    50     }
    51     return dfs(tot, 0, 0, 0);
    52 }
    53 int main(){
    54     while(cin >> l >> r >> k){
    55         memset(dp, -1, sizeof(dp));
    56         ll ans = solve(r)-solve(l-1);
    57         cout << ans << endl;
    58     }
    59     return 0;
    60 }
    View Code

    hdu3652

    问:1~n有多少个数含有连续的“13”并且能被13整除。

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 int dp[11][13][10][2];
     5 int temp[20], tot;
     6 
     7 int dfs(int pos, int mod, int pre, bool tag13, bool flag){
     8     if(!pos)
     9         return (mod == 0&&tag13);
    10     if(flag&&~dp[pos][mod][pre][tag13]) return dp[pos][mod][pre][tag13];
    11     int Max = flag? 9: temp[pos];
    12 
    13     int ans = 0;
    14     for(int i = 0; i <= Max; i++)
    15         ans += dfs(pos-1, (mod*10+i)%13, i, tag13||(pre == 1&&i == 3), flag||i != Max);
    16     if(flag) dp[pos][mod][pre][tag13] = ans;
    17     return ans;
    18 }
    19 
    20 int solve(int x){
    21     tot = 0;
    22     while(x){
    23         temp[++tot] = x%10;
    24         x /= 10;
    25     }
    26     return dfs(tot, 0, 0, 0, 0);
    27 }
    28 int main(){
    29     memset(dp, -1, sizeof(dp));
    30     int n;
    31     while(cin >> n){
    32         ll ans = solve(n)-solve(0);
    33         cout << ans << endl;
    34     }
    35     return 0;
    36 }
    View Code

    hdu4734

    问:0~B中有多少数字各个数位权值和小于 f(A).

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int lim;
     4 int dp[10][9<<9];
     5 int temp[20], tot;
     6 int dfs(int pos, int sum, bool flag){
     7     if(!pos)
     8         return 1;
     9     if(flag&&~dp[pos][sum]) return dp[pos][sum];
    10     int Max = flag? 9: temp[pos];
    11     int ans = 0;
    12     for(int i = 0; i <= Max; i++){
    13         if( (i<<(pos-1)) <= sum )
    14             ans += dfs(pos-1, sum-(i << (pos-1)), flag||i != Max);
    15     }
    16     if(flag) dp[pos][sum] = ans;
    17     return ans;
    18 }
    19 
    20 int solve(int x){
    21     tot = 0;
    22     while(x){
    23         temp[++tot] = x%10;
    24         x /= 10;
    25     }
    26     return dfs(tot, lim, 0);
    27 }
    28 int main(){
    29     memset(dp, -1, sizeof(dp));
    30     int t, a, b, ca = 1; scanf("%d", &t);
    31     while(t--){
    32         scanf("%d%d", &a, &b);
    33         lim = 0;
    34         for(int i = 0; a; i++){
    35             lim += (a%10)<<i;
    36             a /= 10;
    37         }
    38         // lim < (9*2^9)
    39         int ans = solve(b)-solve(0)+1;
    40         printf("Case #%d: %d
    ", ca++, ans);
    41     }
    42     return 0;
    43 }
    View Code

    hdu4507

    问:l~r中与7无关的数的平方和。与7无关的数定义为:不含数字7,不是7的倍数,且各位数和不是7的倍数。

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int P = 1e9+7;
     5 ll f[22];
     6 ll l, r;
     7 struct p{
     8     ll x, y, z;
     9     p(){}
    10     p(ll x, ll y, ll z):x(x), y(y), z(z){}
    11 };
    12 p dp[22][7][7];
    13 int temp[22], tot;
    14 void ad(ll& a, ll b){
    15     a += b;
    16     if(a < 0) a = a%P+P;
    17     if(a >= P) a %= P;
    18 }
    19 p dfs(int pos, int add, int mod, bool flag){
    20     if(!pos)
    21         return p(add&&mod, 0, 0);
    22     if(flag&&dp[pos][add][mod].x != -1) return dp[pos][add][mod];
    23 
    24     int Max = flag? 9: temp[pos];
    25     ll ans = 0, sum = 0, sum2 = 0;
    26     for(int i = 0; i <= Max; i++) if(i != 7){
    27         p ret = dfs(pos-1, (add+i)%7, (mod*10+i)%7, flag||i != Max);
    28         //i*10^(pos-1)+x
    29         ll tmp = f[pos-1]*i%P;
    30         ans += ret.x;
    31         ad(sum, (ret.y+ret.x%P*tmp)%P);
    32         ad(sum2, (ret.x%P*tmp%P*tmp%P+2*tmp*ret.y%P+ret.z)%P);
    33     }
    34     if(flag) dp[pos][add][mod] = p(ans, sum, sum2);
    35     //printf("pos %d, add %d, mod %d, flag %d: %lld %lld %lld
    ", pos, add, mod, flag*1, ans, sum, sum2);
    36     return p(ans, sum, sum2);
    37 }
    38 
    39 
    40 ll solve(ll x){
    41     tot = 0;
    42     while(x){
    43         temp[++tot] = x%10;
    44         x /= 10;
    45     }
    46     return dfs(tot, 0, 0, 0).z;
    47 }
    48 int main(){
    49     f[0] = 1;
    50     for(int i = 1; i <= 20; i++) f[i] = f[i-1]*10%P;
    51     memset(dp, -1, sizeof(dp));
    52     int t, a, b, ca = 1; scanf("%d", &t);
    53     while(t--){
    54         scanf("%lld%lld", &l, &r);
    55         ll ans = solve(r)-solve(l-1);
    56         ans %= P;
    57         if(ans < 0) ans += P;
    58         printf("%lld
    ", ans);
    59     }
    60     return 0;
    61 }
    View Code

    hdu3709

    问:l~r中有多少数字是平衡数? 平衡数的定义为能在数字中找到某一个点作为支点使左边的力矩和右边的力矩相等?如4139,以3为支点时左边是4*2+1*1 = 9, 右边是9*1 = 9.

     1 #include <bits/stdc++.h>
     2 #define ll unsigned long long
     3 using namespace std;
     4 ll dp[22][22][600+600];
     5 ll l, r;
     6 
     7 int temp[22], tot;
     8 
     9 ll dfs(int pos, bool pre, int pivot, int now, bool flag){
    10     if(!pos)
    11         return now == 0;
    12     if(flag&&~dp[pos][pivot][600+now]) return dp[pos][pivot][600+now];
    13 
    14     int Max = flag? 9: temp[pos];
    15     ll ans = 0;
    16     for(int i = 0; i <= Max; i++){
    17         if(!pre&&pivot == pos&&!i) continue ;
    18         int ret = now+(pos-pivot)*i;
    19         if(ret > 550||ret < -550) continue ;
    20         ans += dfs(pos-1, pre||i, pivot, ret, flag||i != Max);
    21     }
    22 
    23     if(flag) dp[pos][pivot][600+now] = ans;
    24     return ans;
    25 }
    26 
    27 
    28 ll solve(ll x){
    29     tot = 0;
    30     while(x){
    31         temp[++tot] = x%10;
    32         x /= 10;
    33     }
    34     ll ans = 0;
    35     for(int i = 1; i <= tot; i++)
    36         ans += dfs(tot, 0, i, 0, 0);
    37     return ans;
    38 }
    39 int main(){
    40     memset(dp, -1, sizeof(dp));
    41     int t, ca = 1; scanf("%d", &t);
    42     while(t--){
    43         cin >> l >> r;
    44         ll ans = 0;
    45         if(l == 0) l++, ans++;
    46         ans += solve(r)-solve(l-1);
    47         cout << ans << endl;
    48     }
    49     return 0;
    50 }
    View Code

    SPOJ Balanced Numbers

    问:l~r有多少数字满足奇数数字出现偶数次偶数数字出现奇数次。

     1 #include <bits/stdc++.h>
     2 #define ll unsigned long long
     3 using namespace std;
     4 //3^10 = 59049
     5 ll f[11];
     6 ll dp[22][2][59050];
     7 ll l, r;
     8 
     9 int temp[22], tot;
    10 bool judge(int x){
    11     bool tag = true;
    12     while(x){
    13         int ret = x%3;
    14         if(ret){
    15             ret &= 1;
    16             if(ret != tag) return false;
    17         }
    18         tag = !tag;
    19         x /= 3;
    20     }
    21     return true;
    22 }
    23 ll dfs(int pos, bool pre, int now, bool flag){//pre == true 1
    24 //    printf("%d %d %d %d
    ", pos, pre*1, now, flag*1);
    25     if(!pos)
    26         return judge(now);
    27     if(flag&&~dp[pos][pre][now]) return dp[pos][pre][now];
    28 
    29     int Max = flag? 9: temp[pos];
    30     ll ans = 0;
    31     for(int i = 0; i <= Max; i++){
    32         int ret = 0;//3^j
    33         if(i||pre){
    34             ret = (now/f[i])%3;
    35             if(ret < 2) ret = now+f[i];
    36             else ret = now-f[i];
    37         }
    38         ans += dfs(pos-1, pre||i, ret, flag||i != Max);
    39     }
    40 
    41     if(flag) dp[pos][pre][now] = ans;
    42     //printf("pos %d, add %d, mod %d, flag %d: %lld %lld %lld
    ", pos, add, mod, flag*1, ans, sum, sum2);
    43     return ans;
    44 }
    45 
    46 
    47 ll solve(ll x){
    48     tot = 0;
    49     while(x){
    50         temp[++tot] = x%10;
    51         x /= 10;
    52     }
    53     return dfs(tot, 0, 0, 0);
    54 }
    55 int main(){
    56     f[0] = 1;
    57     for(int i = 1; i < 11; i++) f[i] = f[i-1]*3;
    58     memset(dp, -1, sizeof(dp));
    59     int t, ca = 1; scanf("%d", &t);
    60     while(t--){
    61         cin >> l >> r;
    62         ll ans = solve(r)-solve(l-1);
    63         cout << ans << endl;
    64     }
    65     return 0;
    66 }
    View Code

    hdu4352

    问:l~r有多少数字的严格最长上升子序列是k?

    题解:状压。dp[还剩i位][k][二进制位下的最长上升子序列]

     1 #include <bits/stdc++.h>
     2 #define ll unsigned long long
     3 using namespace std;
     4 const int N = 1e5+5;
     5 const int P = 1e9+7;
     6 ll dp[11][22][1<<11];
     7 ll l, r, k;
     8 
     9 int temp[22], tot;
    10 ll dfs(int pos, int k, int now, bool flag){
    11     if(!pos)
    12         return __builtin_popcount(now) == k;
    13     if(flag&&~dp[k][pos][now]) return dp[k][pos][now];
    14 
    15     int Max = flag? 9: temp[pos];
    16     ll ans = 0;
    17     for(int i = 0; i <= Max; i++) {
    18         if(!now&&!i) {
    19             ans += dfs(pos-1, k, now, flag||i != Max);
    20             continue ;
    21         }
    22         int ret = now;
    23         if( !((ret>>i)&1) ){//ret[i] : 0
    24             if( ret>>i ){
    25                 for(int j = i+1; j; j++)
    26                     if((ret>>j)&1){
    27                         ret ^= 1<<j;
    28                         break;
    29                     }
    30             }
    31             ret |= 1<<i;
    32         }
    33         ans += dfs(pos-1, k, ret, flag||i != Max);
    34     }
    35 
    36     if(flag) dp[k][pos][now] = ans;
    37     return ans;
    38 }
    39 
    40 
    41 ll solve(ll x){
    42     tot = 0;
    43     while(x){
    44         temp[++tot] = x%10;
    45         x /= 10;
    46     }
    47     return dfs(tot, k, 0, 0);
    48 }
    49 int main(){
    50     memset(dp, -1, sizeof(dp));
    51 
    52     int t, ca = 1; scanf("%d", &t);
    53     while(t--){
    54         cin >> l >> r >> k;
    55         ll ans = solve(r)-solve(l-1);
    56         printf("Case #%d: ", ca++);
    57         cout << ans << endl;
    58     }
    59     return 0;
    60 }
    View Code

    Codeforces 55D

    问:l~r有多少数字可以被各个位上的非0数字整除?

     1 #include <bits/stdc++.h>
     2 #define ll unsigned long long
     3 using namespace std;
     4 const int P = 2520;
     5 ll dp[20][1<<7][2550];
     6 ll l, r;
     7 int w[10][4] = {
     8     {0, 0, 0, 0},
     9     {0, 0, 0, 0},
    10     {1, 0, 0, 0},
    11     {0, 1, 0, 0},
    12     {2, 0, 0, 0},
    13     {0, 0, 1, 0},
    14     {1, 1, 0, 0},
    15     {0, 0, 0, 1},
    16     {3, 0, 0, 0},
    17     {0, 2, 0, 0}
    18 };
    19 int temp[22], tot;
    20 ll dfs(int pos, int k, int now, bool flag){
    21     //printf("%d %d %d
    ", pos, k, now);
    22     if(!pos){
    23         int a2 = k&3, a3 = (k>>2)&3, a5 = (k>>4)&1, a7 = k>>5;
    24         if(a2 == 1&&now%2) return 0;
    25         if(a2 == 2&&now%4) return 0;
    26         if(a2 == 3&&now%8) return 0;
    27         if(a3 == 1&&now%3) return 0;
    28         if(a3 == 2&&now%9) return 0;
    29         if(a5&&now%5) return 0;
    30         if(a7&&now%7) return 0;
    31         return 1;
    32     }
    33     if(flag&&~dp[pos][k][now]) return dp[pos][k][now];
    34 
    35     int Max = flag? 9: temp[pos];
    36     ll ans = 0;
    37     int ret[4], ret2[4];
    38     ret[0] = k&3, ret[1] = (k>>2)&3, ret[2] = (k>>4)&1, ret[3] = k>>5;
    39     for(int i = 0; i <= Max; i++) {
    40         for(int j = 0; j < 4; j++)
    41             ret2[j] = max(ret[j], w[i][j]);
    42         int r = ret2[0]+(ret2[1]<<2)+(ret2[2]<<4)+(ret2[3]<<5);
    43         ans += dfs(pos-1, r, (now*10+i)%2520, flag||i != Max);
    44     }
    45 
    46     if(flag) dp[pos][k][now] = ans;
    47     //printf("%d %d %d: %lld
    ", pos, k, now, ans);
    48     return ans;
    49 }
    50 
    51 
    52 ll solve(ll x){
    53     tot = 0;
    54     while(x){
    55         temp[++tot] = x%10;
    56         x /= 10;
    57     }
    58     return dfs(tot, 0, 0, 0);
    59 }
    60 int main(){
    61     memset(dp, -1, sizeof(dp));
    62     int t, ca = 1; scanf("%d", &t);
    63     while(t--){
    64         cin >> l >> r;
    65         ll ans = solve(r)-solve(l-1);
    66         cout << ans << endl;
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    泛型应用----泛型接口、泛型方法、泛型数组、泛型嵌套
    有选择性的启用SAP UI5调试版本的源代码
    SAP UI5应用入口App.controller.js是如何被UI5框架加载的?
    SAP WebIDE里UI5应用的隐藏文件project.json
    SAP UI5的support Assistant
    如何用SAP WebIDE的Fiori创建向导基于ABAP OData service快速创建UI5应用
    SAP Cloud Platform上Destination属性为odata_gen的具体用途
    Marketing Cloud contact主数据的csv导入
    Marketing Cloud的contact merge机制
    如何让某些用户对Marketing Cloud的contact数据只能实施只读操作
  • 原文地址:https://www.cnblogs.com/dirge/p/6028794.html
Copyright © 2020-2023  润新知