uestc 1307 windy数 数位DP
题目链接:http://acm.uestc.edu.cn/problem.php?pid=1307
windy数的含义是:
不含前导零且相邻两个数字之差至少为2的正整数
题目想知道在A和B之间,包括A和B,总共有多少个windy数?
简单的数位DP
代码:
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 int dp[15][10];//dp[i][j]表示长度为i且最高位为j的windy数的个数 7 void init() 8 { 9 memset(dp,0,sizeof(dp)); 10 for(int i=0;i<10;i++) dp[1][i]=1; 11 for(int i=2;i<=10;i++) 12 for(int j=0;j<10;j++) 13 { 14 for(int k=0;k<=j-2;k++) 15 dp[i][j]+=dp[i-1][k]; 16 17 18 for(int k=j+2;k<10;k++) 19 dp[i][j]+=dp[i-1][k]; 20 } 21 22 } 23 int bit[20]; 24 int solve(int n) 25 { 26 if(n==0) return 0; 27 int len=0; 28 while(n) 29 { 30 bit[++len]=n%10; 31 n/=10; 32 } 33 bit[len+1]=-10; 34 35 int ans=0; 36 37 bool flag=1; 38 for(int i=1;i<len;i++)//先计入长度小于len的 39 for(int j=1;j<=9;j++) 40 ans+=dp[i][j]; 41 for(int j=1;j<bit[len];j++)//再计入最高位 42 ans+=dp[len][j]; 43 44 45 for(int i=len-1;i>=1;i--) 46 { 47 for(int j=0;j<bit[i];j++) 48 if(abs(bit[i+1]-j)>=2) 49 ans+=dp[i][j]; 50 if(abs(bit[i+1]-bit[i])<2) 51 { 52 flag=0; 53 break; 54 } 55 } 56 if(flag ) ans++; 57 return ans; 58 } 59 int main() 60 { 61 int a,b; 62 init(); 63 while(scanf("%d%d",&a,&b)!=EOF) 64 { 65 cout<<solve(b)-solve(a-1)<<endl; 66 67 } 68 return 0; 69 }