hdu_3565_Bi-peak Number(数位DP)

37 篇文章 0 订阅

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3565

题意:给你一个区间,让你找这个区间内有两个山峰的数的最大和,什么是两个山峰,比如121121  第一个2 和第二个2就是两个峰

题解:求的这个不满足dfs(y)-dfs(x)所以只有用一个上限和一个下限来限制

s=0:前导0的状态;
s=1:第一个山峰的上坡,且不能立马下坡;
s=2:第一个山峰的上坡,且最后一点能看成是最高点,下一个点可以是下坡;
s=3:第一个山峰的下坡;
s=4:第二个山峰的上坡,且不能立马下坡;
s=5:第二个山峰的上坡,且最后一点能看成是最高点,下一个点可以是下坡;
s=6:第二个山峰的下坡;
s=-1:其余不合法的状态。

设dp[i][j][k]为考虑第i位,上一个数字为j,状态s为k的最大数位和

#include<cstdio>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define F(i,a,b) for(int i=a;i<=b;i++)

int dp[25][10][7],ss[25],ee[25],t,len,an;unsigned __int64 x,y;

int dfs(int pos,int pre,int s,int fx,int fy){
    if(!pos)return s==6?0:-1;
    if(!fx&&!fy&&dp[pos][pre][s]!=-2)return dp[pos][pre][s];
    int st=fx?ss[pos]:0,end=fy?ee[pos]:9,ans=-1,tp,ns;
    F(i,st,end){
		ns=s;
        if(!s&&i)ns=1;
        else if(s==1){if(i>pre)ns=2;else ns=-1;}
        else if(s==2){if(i<pre)ns=3;else if(i==pre)ns=-1;}
        else if(s==3&&i>=pre){if(i)ns=4;else ns=-1;}
        else if(s==4){if(i>pre)ns=5;else ns=-1;}
        else if(s==5){if(i<pre)ns=6;else if(i==pre)ns=-1;}
        else if(s==6&&i>=pre)ns=-1;
        if(ns!=-1)tp=dfs(pos-1,i,ns,fx&&i==st,fy&&i==end),ans=(tp==-1?ans:MAX(ans,i+tp));
    }
    if(!fx&&!fy)dp[pos][pre][s]=ans;
    return ans;
}

int main(){
    F(i,0,24)F(j,0,9)F(k,0,6)dp[i][j][k]=-2;
    scanf("%d",&t);
    F(i,1,t){
        scanf("%I64u%I64u",&x,&y);
        for(len=0;y;x/=10,y/=10)ss[++len]=x%10,ee[len]=y%10;
        an=dfs(len,0,0,1,1),printf("Case %d: %d\n",i,an==-1?0:an);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值