首页 > 代码库 > [数位dp] hdu 3565 Bi-peak Number
[数位dp] hdu 3565 Bi-peak Number
题意:
给范围[X,Y],求范围内双峰数位数和最大值是多少。
双峰数定义就是满足一个数 可以分割成两个 /\ /\ 的形式。
思路:
dp[site][cur][ok] site位 前面的数是cur 状态为ok
ok分为7种
0:前面所有数都是0
1:第一个峰数且只有一个数
2:第一个峰数在峰顶(可上可下)
3:第一个峰数在峰底(可进入下一个峰或者继续往下)
4:同1 是第二个峰数
5:同2 是第二个峰数
6:同3 但是不可进入下一个峰数了
代码:
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"algorithm" #include"iostream" using namespace std; #define ll unsigned __int64 int dp[30][10][7]; int numx[30],numy[30]; int dfs(int site,int cur,int ok,int fa,int fb) //因为是大小 所以要在中间判断 { if(site==0) return ok==6?0:-1; //状态6代表成立的数 if(!fa&&!fb&&~dp[site][cur][ok]) return dp[site][cur][ok]; //都不是边界 int Min=fa?numx[site]:0; //上界 int Max=fb?numy[site]:9; //下界 int ans=-1; //初值 for(int i=Min; i<=Max; i++) { int tep=0; if(ok==0&&i) tep=1; //去前导0 else if(ok==1) { if(i>cur) tep=2; //往上走 else tep=-1; //无法走 } else if(ok==2) { if(i>cur) tep=2; //继续上 else if(i==cur) tep=-1; //相等不能走 else tep=3; //往下 } else if(ok==3) { if(i>cur) tep=4; //跳到第二个峰 else if(i==cur) //相等的话0不能跳,因为不能前导0 { if(i) tep=4; else tep=-1; } else tep=3; //继续下 } else if(ok==4) //下同上 { if(i>cur) tep=5; else tep=-1; } else if(ok==5) { if(i>cur) tep=5; else if(i==cur) tep=-1; else tep=6; } else if(ok==6) { if(i>=cur) tep=-1; //最后只能下不能跳了 else tep=6; } if(tep!=-1) { int sum=dfs(site-1,i,tep,fa&&i==Min,fb&&i==Max); //这位放完 后面的最大值 if(sum!=-1) ans=max(ans,sum+i); //加上这位比大小 } } if(!fa&&!fb) dp[site][cur][ok]=ans; //不是边界保存值 return ans; } int main() { int t,cas=1; cin>>t; memset(dp,-1,sizeof(dp)); while(t--) { ll x,y; scanf("%I64u%I64u",&x,&y); //注意2^64次方 要用无符号64位读入 int cnt=0; while(y) { cnt++; numx[cnt]=x%10; x/=10; numy[cnt]=y%10; y/=10; } int ans=dfs(cnt,0,0,1,1); printf("Case %d: %d\n",cas++,ans==-1?0:ans); } return 0; }
[数位dp] hdu 3565 Bi-peak Number
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。