HDU 2089 不要62
刚学的数位DP。
dp[i][j]表示,长度为i的数字,并且最高位为j的情况下的吉利的数字有几个
很显然dp[i][j]是由dp[i-1][0,1,2,3,.....9]推导而来的
处理出dp数组之后,我们能在o(1)效率内得到比某个数字小的吉利数有几个,然后容斥原理一减就是答案
#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[15][15]; int p[15]; int tot; int a,b; int f(int x) { tot=0; while(x) { p[tot++]=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=0; i<tot; i++) { for(int j=0; j<p[i]; j++) { if(j==4) continue; if(j==2&&p[i-1]==6) continue; else res=res+dp[tot-i][j]; } if(p[i]==4) break; if(p[i]==2&&p[i-1]==6&&i-1>=0) break; } return res; } void init() { memset(dp,0,sizeof dp); for(int i=0; i<=9; i++) dp[1][i]=1; dp[1][4]=0; for(int i=2; i<=7; i++) { for(int j=0; j<=9; j++) { if(j==4) { dp[i][j]=0; continue; } for(int k=0; k<=9; k++) { if(j==6&&k==2) continue; else dp[i][j]=dp[i][j]+dp[i-1][k]; } } } } int main() { init(); while(~scanf("%d%d",&a,&b)) { if(!a&&!b) break; printf("%d\n",f(b+1)-f(a)); } return 0; }