zoukankan      html  css  js  c++  java
  • HDOJ 3565 Bipeak Number (数位DP)

    Problem Description:
    A peak number is defined as continuous digits {D0, D1 … Dn-1} (D0 > 0 and n >= 3), which exist Dm (0 < m < n - 1) satisfied Di-1 < Di (0 < i <= m) and Di > Di+1 (m <= i < n - 1).
    A number is called bi-peak if it is a concatenation of two peak numbers.



    The score of a number is the sum of all digits. Love8909 is crazy about bi-peak numbers. Please help him to calculate the MAXIMUM score of the Bi-peak Number in the closed interval [A, B].
     
    分析:由于结果不满足区间减法,所以不能像通常那样计算cal(b)-cal(a-1),正确的处理方法是,在dfs时保存2个标记,一个标记前缀是否达上界,另一个标记是否达下界。然后就是状态分析了,分析清楚了也就简单了,以下是我设计的状态:
    s=0:前导0的状态;
    s=1:第一个山峰的上坡,且不能立马下坡;
    s=2:第一个山峰的上坡,且最后一点能看成是最高点,下一个点可以是下坡;
    s=3:第一个山峰的下坡;
    s=4:第二个山峰的上坡,且不能立马下坡;
    s=5:第二个山峰的上坡,且最后一点能看成是最高点,下一个点可以是下坡;
    s=6:第二个山峰的下坡;
    s=-1:其余不合法的状态。
    View Code
    #include <stdio.h>
    #include <string.h>
    #define MAX(a,b) ((a)>(b)?(a):(b))
    #define N 20
    #define INF 0x7f7f7f7f
    typedef unsigned __int64 LL;
    int sx[N],sy[N];
    int dp[N][10][7];
    int dfs(int pos,int last,int s,int fx,int fy)
    {
        if(pos==-1) return s==6?0:-1;
        if(!fx&&!fy&&dp[pos][last][s]!=INF)    return dp[pos][last][s];
        int min=fx?sx[pos]:0;
        int max=fy?sy[pos]:9;
        int ret=-1;
        for(int i=min;i<=max;i++)
        {
            int ns=s;
            if(s==0 && i)  ns=1;
            else if(s==1)
            {
                if(i>last)  ns=2;
                else    ns=-1;
            }
            else if(s==2)
            {
                if(i<last)  ns=3;
                else if(i==last)    ns=-1;
            }
            else if(s==3 && i>=last)
            {
                if(i)   ns=4;
                else    ns=-1;
            }
            else if(s==4)
            {
                if(i>last)  ns=5;
                else    ns=-1;
            }
            else if(s==5)
            {
                if(i<last)  ns=6;
                else if(i==last)    ns=-1;
            }
            else if(s==6 && i>=last) ns=-1;
            if(ns!=-1)
            {
                int tmp=dfs(pos-1,i,ns,fx&&i==min,fy&&i==max);
                if(tmp!=-1) ret=MAX(ret,i+tmp);
            }
        }
        if(!fx&&!fy)  dp[pos][last][s]=ret;
        return ret;
    }
    int main()
    {
        int t,kase=0;
        memset(dp,0x7f,sizeof(dp));
        scanf("%d",&t);
        while(t--)
        {
            printf("Case %d: ",++kase);
            LL x,y;
            scanf("%I64u%I64u",&x,&y);
            int pos=0;
            for(;y;x/=10,y/=10) sx[pos]=x%10,sy[pos++]=y%10;
            int ans=dfs(pos-1,0,0,1,1);
            if(ans==-1) ans=0;
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    Nginx 部署多个 web 项目(虚拟主机)
    Nginx 配置文件
    Linux 安装 nginx
    Linux 安装 tomcat
    Linux 安装 Mysql 5.7.23
    Linux 安装 jdk8
    Linux 安装 lrzsz,使用 rz、sz 上传下载文件
    springMVC 拦截器
    spring 事务
    基于Aspectj 注解实现 spring AOP
  • 原文地址:https://www.cnblogs.com/algorithms/p/2669727.html
Copyright © 2011-2022 走看看