标签:数位dp
#include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <stack> #include <queue> #include <set> #include <map> #include <vector> #include <cmath> #include <cstring> using namespace std; int dp[10][3]; //dp[i][j] 表示数字的位数,j代表状态 //dp[i][0] 表示不存在不吉利的数字 //dp[i][1] 表示不存在吉利数字,且最高位是2 //dp[i][2] 表示存在不吉利数字 void init(){ memset(dp,0,sizeof(dp)); dp[0][0] = 1;//初始化一下0位的不吉利数字为1 for(int i = 1;i <= 7;i++){ dp[i][0] = dp[i-1][0]*9 - dp[i-1][1];//最高位不含有4的9个数字,而且因为当放第i位放6的时候,i-1不能放2所以要减去一下i-1位不存在不吉利数字切最高位为2 的情况 dp[i][1] = dp[i-1][0];//最高位放了2其他位只要不是不吉利数字就可以 dp[i][2] = dp[i-1][2] * 10 +dp[i-1][0] + dp[i-1][1];//i位的含有不吉利数字的个数是i-1位的含有不吉利数字的×10,因为只要后面含有不吉利数字前面不管是什么都可以所以前面×10,另外如果最高位放一个4然后后面的全部不是不吉利数字就行,还可以是最高位放上一个6然后,倒数第二位放上2就可以的不是不吉利就行 } } int fun(int n){ int len = 0,tem = n,ans,flag,a[10]; while(n){ a[++len] = n%10; n /= 10; } a[len+1] = ans = 0; flag = 0; //求出1-(n-1)之间的不吉利的数 for(int i = len;i >= 1;i--){ ans += dp[i-1][2] * a[i];//后面的i-1是不吉利数字之后前面就可以填上任意的 if(flag){ ans += dp[i-1][0] * a[i]; } if(!flag && a[i] > 4){ ans += dp[i-1][0];//如果a[i]>4那么就可以在i位上放上一个4 } if(!flag && a[i+1] == 6 && a[i] > 2){//如果后一位是6这一位是大于2的 ans += dp[i][1]; } if(!flag && a[i] > 6){ ans += dp[i-1][1]; } if(a[i] == 4 || a[i+1] == 6 && a[i] == 2){ flag = 1; } } return tem - ans; } int main() { int n,m; init(); while(cin >> n >> m,n||m){ printf("%d\n",fun(m+1) - fun(n)); } return 0; }
标签:数位dp
原文地址:http://blog.csdn.net/qq_24667639/article/details/45460953