数位DP练习

来源:互联网 发布:股票行情软件哪家好 编辑:程序博客网 时间:2024/06/05 20:51

数位DP模板http://blog.csdn.net/gengman/article/details/78315360



HDU2089  不要62

奋斗

题意:求区间中不含62且不含4的数的个数 #include<stdio.h>#include<algorithm>#include<string.h> using namespace std;int dp[20][10]; int a[20];//sta 记录上一位数是否是6 int dfs(int pos,int sta,bool limit){if(pos==-1) return 1;if(!limit&&dp[pos][sta]!=-1) return dp[pos][sta];int up=limit?a[pos]:9;int ans=0;for(int i=0;i<=up;i++){if(i==4) continue;if(sta&&i==2) continue;ans+=dfs(pos-1,i==6,limit&&i==a[pos]);}if(!limit) dp[pos][sta]=ans;return ans;}int solve(int x){int pos=0;while(x){a[pos++]=x%10;x/=10;}return dfs(pos-1,0,true);}int main(){int l,r;memset(dp,-1,sizeof(dp));while(~scanf("%d%d",&l,&r)){if(l==0&&r==0){return 0;}printf("%d\n",solve(r)-solve(l-1));}return 0;} 




HDU3555

和不要62差不多 

求1-N中包含49的数的个数



HDU3652

题意:统计1-n中含有13且能被13整除的数的个数 #include<stdio.h>#include<algorithm>#include<string.h> using namespace std;typedef long long LL;int dp[10][15][2][10];//注意数组大小 int a[20];//pos位置//mod 前面的数%13的结果//sta 是否已经包含13//pre 上一位的数 int dfs(int pos,int mod,int sta,int pre,bool limit){if(pos==-1) return mod==0&&sta;if(!limit&&dp[pos][mod][sta][pre]!=-1) return dp[pos][mod][sta][pre];int up=limit?a[pos]:9;int ans=0;for(int i=0;i<=up;i++){ans+=dfs(pos-1,(mod*10+i)%13,sta||(pre==1&&i==3),i,limit&&i==a[pos]);}if(!limit) dp[pos][mod][sta][pre]=ans;return ans;}int solve(int x){int pos=0;while(x){a[pos++]=x%10;x/=10;}return dfs(pos-1,0,0,0,true);}int main(){int n;memset(dp,-1,sizeof(dp));while(~scanf("%d",&n)){printf("%d\n",solve(n));}return 0;}




HDU5898


题意:统计L-R之间连续的奇数必须是偶数个,连续的偶数必须是奇数个。。的个数#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;typedef long long LL;int a[20];LL dp[20][11][20];//dp[i][j][k]前i位上一位是j,连续的奇数/偶数个数为k LL dfs(int pos,int sta,int pre,bool lead,bool limit ){if(pos==-1) return (sta+pre)%2;if(!limit&&!lead&&dp[pos][sta][pre]!=-1) return dp[pos][sta][pre];int up=limit?a[pos]:9;LL ans=0;if(lead){for(int i=0;i<=up;i++){ans+=dfs(pos-1,i,1,lead&&i==0,limit&&i==a[pos]);}} else if((sta+pre)%2){for(int i=0;i<=up;i++){if((sta+i)%2==0)ans+=dfs(pos-1,i,pre+1,lead&&i==0,limit&&i==a[pos]);else ans+=dfs(pos-1,i,1,lead&&i==0,limit&&i==a[pos]);}}else{for(int i=0;i<=up;i++){ if((sta+i)%2==0)ans+=dfs(pos-1,i,pre+1,lead&&i==0,limit&&i==a[pos]);}}if(!limit&&!lead) dp[pos][sta][pre]=ans;return ans;} LL solve(LL x){int pos=0;while(x){a[pos++]=x%10;x/=10;}return dfs(pos-1,10,1,true,true);}int main(){int T,t=0;scanf("%d",&T);memset(dp,-1,sizeof(dp));while(T--){LL l,r;scanf("%lld%lld",&l,&r);printf("Case #%d: %lld\n",++t,solve(r)-solve(l-1));}}


原创粉丝点击