BZOJ 1026 [SCOI2009]windy数
数位DP
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <vector> #include <cmath> #include <map> #include <string> using namespace std; int dp[25][25]; int p[25]; int tot; int a,b; void init() { memset(dp,0,sizeof dp); for(int i=0;i<=9;i++) dp[1][i]=1; for(int i=2;i<=20;i++) { for(int j=0;j<=9;j++) { int sum=0; for(int k=0;k<=9;k++) if(abs(k-j)>=2) sum=sum+dp[i-1][k]; dp[i][j]=sum; } } } int f(int x) { tot=0; while(x) { p[tot++]=(int)(x%10); x=x/10; } for(int i=0; i<tot/2; i++) swap(p[i],p[tot-i-1]); int res=0; for(int i=1;i<tot;i++) { for(int j=1;j<=9;j++) { res=res+dp[i][j]; } } for(int j=1;j<p[0];j++) res=res+dp[tot][j]; for(int i=1;i<tot;i++) { for(int j=0;j<p[i];j++) { if(i==0||abs(j-p[i-1])>=2) res=res+dp[tot-i][j]; } if(abs(p[i]-p[i-1])<=1) break; } return res; } int main() { init(); while(~scanf("%d%d",&a,&b)){ printf("%d\n",f(b+1)-f(a)); } return 0; }