数位dp

常见表示:

Dp[i][j] = 符合要求且以数字j为首位的i位数的个数

Dp[i][j] = 符合要求且处于状态j的i位数的个数,如j=0/1表示首位不是/是4

步骤:
init(); // 计算所有的dp[][]
solve(n); // 计算[0, n]的答案
[l, r] = solve(r) – solve(l - 1); 

 

 1 long long dp[10][10]={0};
 2 void init()
 3 {
 4     dp[0][0]=1;
 5     for(int i=1;i<=7;i++){
 6         for(int j=0;j<=9;j++){//枚举第i位
 7             for(int k=0;k<=9;k++){//枚举第i-1位
 8                 if(符合要求) continue;
 9                 dp[i][j]+=dp[i-1][k];
10             }
11         }
12     }
13 }
 1 int num[10];
 2 long long solve(long long n)
 3 {
 4     long long t=0;
 5     memset(num,0,sizeof(num));
 6     while(n){
 7         num[++t]=n%10;
 8         n/=10;
 9     }
10     num[t+1]=0;
11     long long ans=0;
12     for(int i=t;i>0;i--){//枚举第i位
13         for(int j=0;j<num[i];j++){//枚举第i-1位
14             if(符合条件) continue;
15             ans+=dp[i][j];
16         }
17         if(符合条件) break;
18     }
19     return ans;
20 }

1~m范围:m+1-solve(m+1);

n~m范围:solve(m+1)-solve(n);

 

 

你可能感兴趣的:(数位dp)