hdu 3565 Bi-peak Number 数位dp

来源:互联网 发布:apache的日志指令 编辑:程序博客网 时间:2024/06/06 04:02


题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3565


题目大意:

各位数字先增后减的数称为峰值数(位数大于等3且第一位非零),然后两个峰值数连在一起是一个bi-peak数,求两个数之间bi-peak数的各位数字之和的最大值。


解题思路:

数位dp,dp[i][j][k]表示当前后面还有i位,j表示前一位的数字,k表示与峰值的状态关系。

k=0 表示前面的为零,k=1表示前面恰好有一个在第一个波峰的上坡上,k=2表示前面至少有两个在第一个波峰的上坡上,k=3表示在第一个波峰的下坡上

                                        k=4表示前面恰好有一个在第二个波峰的上坡上,k=5表示前面至少有两个在第二个波峰的上坡上,k=6表示在第二个波峰的下坡上

注意峰值数的位数至少为3并且第一位非零。


代码:

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<stack>#include<list>#include<queue>#define eps 1e-6#define INF (1<<30)#define PI acos(-1.0)using namespace std;#define ll unsigned __int64int dp[30][15][7];//状态0表示前面都是0,状态1表示第一个上坡后面不能下坡,2表示第一个上坡后面可以是下坡,3表示第一个下坡                      //  4      二                    5      二                      6      二int aa[30],bb[30];int dfs(int cur,int last,int flag,int aflag,int bflag){   if(!cur) //到了最后一位      return (flag==6)?0:-1;   if(!aflag&&!bflag&&dp[cur][last][flag]!=-1)      return dp[cur][last][flag];   int Min=aflag?aa[cur]:0; //下界   int Max=bflag?bb[cur]:9; //上界   int res=-1;   for(int i=Min;i<=Max;i++)   {      int status=0;      if(flag==0&&i)         status=1;      else if(flag==1)      {         if(i>last)            status=2;         else            status=-1;      }      else if(flag==2)      {         if(i<last)            status=3;         else if(i==last)            status=-1;         else            status=2;      }      else if(flag==3)      {         if(i>last)            status=4;         else if(i==last)            {               if(i)                  status=4;               else                  status=-1;            }         else            status=3;       }       else if(flag==4)       {          if(i>last)            status=5;          else            status=-1;       }       else if(flag==5)       {          if(i<last)            status=6;          else if(i==last)            status=-1;          else            status=5;       }       else if(flag==6)       {          if(i<last)            status=6;          else            status=-1;       }      if(status!=-1)      {         int temp=dfs(cur-1,i,status,aflag&&i==Min,bflag&&i==Max);         if(temp!=-1)            res=max(res,i+temp);      }   }   if(!aflag&&!bflag)      dp[cur][last][flag]=res;   return res;}int main(){   int t;   scanf("%d",&t);   memset(dp,-1,sizeof(dp));   for(int ca=1;ca<=t;ca++)   {      ll a,b;      scanf("%I64u%I64u",&a,&b);      int pos=0;      while(b)      {         ++pos;         aa[pos]=a%10;         a/=10;         bb[pos]=b%10;         b/=10;      }      int ans=dfs(pos,0,0,1,1);      printf("Case %d: ",ca);      if(ans!=-1)         printf("%d\n",ans);      else         printf("0\n");   }   return 0;}


原创粉丝点击