[BZOJ1026][SCOI2009]windy数 数位DP

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1026

数位DP,一切都是套路。

首先预处理,然后把最高位区间算满的先加上,然后把不足最高位的加上,然后再来按每一位计算。

数位DP的题都是这样做的。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 int f[15][15];
 7 int solve(int x){
 8     int dig=0,tmp=x,a[15];
 9     while(tmp){
10         a[++dig]=tmp%10;
11         tmp/=10;
12     }
13     int ans=0;
14     for(int i=1;i<a[dig];i++) ans+=f[dig][i];
15     for(int i=1;i<dig;i++)
16         for(int j=1;j<=9;j++)
17             ans+=f[i][j];
18     for(int i=dig-1;i>=1;i--){
19         for(int j=0;j<a[i];j++)
20             if(abs(j-a[i+1])>=2)
21                 ans+=f[i][j];
22         if(abs(a[i+1]-a[i])<2) break;
23     }
24     return ans;
25 }
26 int main(){
27     for(int i=0;i<=9;i++) f[1][i]=1;
28     for(int i=2;i<=10;i++)
29         for(int j=0;j<=9;j++)
30             for(int k=0;k<=9;k++)
31                 if(abs(j-k)>=2)
32                     f[i][j]+=f[i-1][k];
33     int A,B;
34     scanf("%d%d",&A,&B);
35     printf("%d\n",solve(B+1)-solve(A));
36     return 0;
37 }

 

posted @ 2017-08-29 20:42  halfrot  阅读(...)  评论(... 编辑 收藏