常见表示:
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);