zoukankan      html  css  js  c++  java
  • 【区间DP】【lgP3146】248

    传送门

    Description

    给定一个1*n的地图,在里面玩2048,每次可以合并相邻两个(数值范围1-40),问最大能合出多少。注意合并后的数值并非加倍而是+1,例如2与2合并后的数值为3。

    Input

    输入的第一行是一个数字n,代表地图大小。然后n行,i+1行代表第i个数的大小

    Output

    输出仅一行,为最大能合并出的大小

    Hint

    1<=n<=248,不保证所有的数字能被合成完

    Sample Input

    4
    1
    1
    1
    2

    Sample Output

    3

    solution

    典型的区间DP。首先考虑区间dp最普通状态定义:用f[i][j]表示区间[i,j]所能合成的最大答案,转移为f[i][j]=max{f[i][k]+1|当且仅当f[i][k]==f[k+1][j]}。输出f[1][n],这么做本题存在缺陷:在转移时,无法保证区间f[i][j]的最大值在所需要的左(右)端点处被取到。例如:观察线段

    此时f[1][3]=5,f[4][6]=5,但是无法进行合并,因为[1,3]等于5的位置在左侧,与[4,6]并不直接相连。

    考虑增加维度,当前转移为n^3,增加维度时间爆炸,否定

    考虑限制状态,记f[i][j]为区间[i,j]恰好能够合成的最大值,每次转移维护ans。转移同上。可行

      对于区间[i,j]的最大值一定可以由其两个子区间的最优解转移得到。

      证明:手推可能hack的情况,发现显然。


    Code

    #include<cstdio>
    #define maxn 250
    
    inline void qr(int &x) {
        char ch=getchar();int f=1;
        while(ch>'9'||ch<'0')    {
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')    x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x*=f;
        return;
    }
    
    inline int max(int a,int b) {return a>b?a:b;}
    inline int min(int a,int b) {return a<b?a:b;}
    
    inline void swap(int &a,int &b) {
        int c=a;a=b;b=c;return;
    }
    
    int n,num[maxn],frog[maxn][maxn],ans;
    
    int main() {
        qr(n);
        for(int i=1;i<=n;++i) {
            qr(num[i]);frog[i][i]=num[i];
        }
        for(int i=1;i<n;++i) {
            for(int j=1;j<=n;++j) {
                int r=j+i;if(r>n)    break;
                for(int k=j;k<r;++k) {
                    if(!(frog[j][k]^frog[k+1][r]))    frog[j][r]=max(frog[j][r],frog[j][k]+1),ans=max(ans,frog[j][r]);
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }

    summary

      对于DP时发现状态不够严谨导致转移困难,可以考虑对状态加以限制。在每次转移时更新答案。

      另外据说这题有大常数O(n)算法。可惜我不会

     

    End on 2018/6/3

  • 相关阅读:
    01-初学总结之《谭浩强C程序设计》
    00-计算机经典参考书籍
    (转)android图片压缩总结
    am等adb命令小总结
    (原创)在service中定时执行网络操作的几点说明
    (转)访问者模式
    (原创)用Receiver和SystemService监听网络状态,注册Receiver的两种方式
    (原创)Activity启动模式之singleTask
    (原创)开发微信公众平台遇到的乱码等问题的解决
    (转载)XML解析之-XStream解析
  • 原文地址:https://www.cnblogs.com/yifusuyi/p/9129359.html
Copyright © 2011-2022 走看看