hdu3555
#include<iostream> #include<algorithm> #include<cstdio> #include<string.h> using namespace std; __int64 dp[30][4]; void init() { memset(dp,0,sizeof(dp)); dp[0][0]=1; for(int i=1; i<=20; i++) { dp[i][0]=dp[i-1][0]*10-dp[i-1][1]; //①:dp[i-1][0]*10代表当前可选择0-9十个数 ②:dp[i-1][1]当前以9开头的数的个数。 //③dp[i-1][0]*10-dp[i-1][1]代表不包含49的个数。 dp[i][1]=dp[i-1][0]; //①dp[i-1][0]代表以9开头的个数的数目 dp[i][2]=dp[i-1][2]*10+dp[i-1][1]; //以49开头的个数(分为两种情况:①dp[i][2]:x49xxx ②当第一个x为4时满足条件dp[i][1]x9xxxx } } int main() { int T,len,flag,num[50]; __int64 t,ans; init(); scanf("%d",&T); while(T--) { len=flag=ans=0; scanf("%I64d",&t); t++; memset(num,0,sizeof(num)); while(t) { num[++len]=t%10; t/=10; } int g=0; for(int i=len; i>0; i--) { ans+=num[i]*dp[i-1][2];//开头为x49的个数 if(flag) { ans+=dp[i-1][0]*num[i];//开头为49的个数 } if(!flag&&num[i]>4) { ans+=dp[i-1][1];//开头为x9(x>4)的个数 } if(g==4&&num[i]==9) { flag=1;//判断。 } g=num[i]; } printf("%I64d\n",ans); } return 0; }
hdu2089
数据比较弱:①可以暴搜②可以用数位DP:
#include<iostream> #include<algorithm> #include<cstdio> #include<string.h> using namespace std; int dp[1000010]; bool f(int i) { while(i) { if(i%10==4||i%100==62) return 1; i/=10; } return 0; } int main() { int n,m; int ans,count; memset(dp,0,sizeof(dp)); for(int i=1; i<1000000; i++) if(f(i)) dp[i]=1; while(scanf("%d%d",&n,&m)) { ans=0; if(n==0&&m==0) break; for(int i=n; i<=m; i++) if(dp[i]==0) ans++; printf("%d\n",ans); } return 0; }
//该题分为三个状态: //① 不含有不吉利的 ② 不含有 不吉利 但是以2开头的 ③ 含有不吉利的 #include<iostream> #include<algorithm> #include<cstdio> #include<string.h> int dp[15][4]; int nu[20]; void init() { memset(dp,0,sizeof(dp)); dp[0][0]=1; for(int i=1; i<=9; i++) { //不含不吉利的数的个数:去掉①含有4的②含有62的 dp[i][0]=dp[i-1][0]*9-dp[i-1][1]; //不含有不吉利的数的个数:以2开头的数的个数 dp[i][1]=dp[i-1][0]; //含有不吉利的数的个数:①含有62的个数②以4开头的个数 dp[i][2]=dp[i-1][2]*10+dp[i-1][1]+dp[i-1][0]; } } int ANS(int num) { memset(nu,0,sizeof(nu)); int len=0; int ans=0; int tem=num; while(num) { nu[++len]=num%10; num/=10; } int flag=0,last=0; for(int i=len; i>0; i--) { ans+=dp[i-1][2]*nu[i];//不吉利的数 if(flag) { ans+=dp[i-1][0]*nu[i];//前面已经出现了不吉利的数 } else { if(nu[i]>4) ans+=dp[i-1][0]; if(nu[i]>6) ans+=dp[i-1][1]; if(last==6&&nu[i]>2) ans+=dp[i][1]; } if(last==6&&nu[i]==2||nu[i]==4) flag=1; last=nu[i]; } return tem-ans; } int main() { int n,m; init(); while(scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; printf("%d\n",ANS(m+1)-ANS(n)); } return 0; }