HDU 3555 (递推&&记忆化)
#include<stdio.h> #include<string.h> #define max 25 typedef __int64 LL; LL dp[max][3]; //dp[i][0] 不含49 //dp[i][1] 不含49但最高位为9 //dp[i][2] 含49 void init(){ memset(dp,0,sizeof(dp)); dp[0][0]=1; for(int i=1;i<max;i++){ dp[i][0]=dp[i-1][0]*10-dp[i-1][1]; dp[i][1]=dp[i-1][0]; dp[i][2]=dp[i-1][2]*10+dp[i-1][1]; } } LL solve(LL n){ int bit[max],len=0; while(n){ bit[++len]=n%10; n/=10; } bit[len+1]=0; LL ans=0; bool flag=false; for(int i=len;i;i--){ ans+=bit[i]*dp[i-1][2]; if(flag){ ans+=bit[i]*dp[i-1][0]; } else{ if(bit[i]>4){ ans+=dp[i-1][1]; } if(bit[i+1]==4&&bit[i]==9){ flag=true; } } } if(flag){ ans++; } return ans; } int main(){ init(); int T; scanf("%d",&T); while(T--){ LL n; scanf("%I64d",&n); printf("%I64d\n",solve(n)); } } #include<stdio.h> #include<string.h> #define max 25 typedef long long LL; LL dp[max][3]; int bit[max],len; LL dfs(int pos,int have,int doing){ if(pos==0){ return have==2; } if(!doing && dp[pos][have]!=-1){ return dp[pos][have]; } LL ans=0; int end=doing?bit[pos]:9; for(int i=0;i<=end;i++){ int nhave=have; if(have==1&&i!=4){ nhave=0; } if(have==0&&i==4){ nhave=1; } if(have==1&&i==9){ nhave=2; } ans+=dfs(pos-1,nhave,doing&&i==end); } if(!doing){ dp[pos][have]=ans; } return ans; } LL solve(LL n){ len=0; while(n){ bit[++len]=n%10; n/=10; } return dfs(len,0,true); } int main(){ memset(dp,-1,sizeof(dp)); int t; scanf("%d",&t); while(t--){ LL n; scanf("%lld",&n); printf("%lld\n",solve(n)); } }
posted on 2013-08-11 15:15 Stomach_ache 阅读(123) 评论(0) 编辑 收藏 举报