[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 }