• 【USACO16OPEN】【luogu3146】248


    题目描述

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

    第一行一个数n,接下来n行,每行一个数。

    输出

    一个数表示最大可以合出多少。


    样例输入

    4
    1
    1
    1
    2


    样例输出

    3


    题解

    明显的区间dp。设 dp[ i ][ j ] 为区间 [ i , j ] 可以合出的最大值,在 [ i , j ] 中枚举 k ,当 dp[ i ][ k ] == dp[ k+1 ][ j ] 时,更新  dp[ i ][ j ] = max( dp[ i ][ j ] , dp[ i ][ k ] + 1 ),但是注意,dp[ i ][ k ] 不能等于0。

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=248+10;
    const int inf=2e9+7;
    
    int dp[maxn][maxn],n,ans=0;
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n);
        for(int i=1;i<=n;i++){
            read(dp[i][i]);
            ans=max(ans,dp[i][i]);
        }
        
        for(int len=2;len<=n;len++)
        for(int i=1;i+len-1<=n;i++){
            int j=i+len-1;
            for(int k=i;k<j;k++)
            if(dp[i][k]==dp[k+1][j]&&dp[i][k]) dp[i][j]=max(dp[i][j],dp[i][k]+1);
            ans=max(ans,dp[i][j]);
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    BGP笔记
    IS-IS笔记
    MAC ACL、RACL和VACL
    MPLS笔记
    OSPF笔记
    RIP笔记
    组播浅谈
    如何查看本机是否是虚拟机
    python中逻辑运算符“+”的特殊之处
    劳动成本持续增高,中国企业如何自救?精益化生产提升企业附加值
  • 原文地址:https://www.cnblogs.com/rlddd/p/9482210.html
Copyright © 2020-2023  润新知