1 条题解

  • 0
    @ 2026-1-27 21:47:36
    #include<bits/stdc++.h>
    using namespace std;
    
    // [1] n-输入的数字个数;arr数组-存储输入的n个数字(下标1~n)
    int n,arr[300];
    // [2] dp[l][r]-区间[l, r]内的数字能合并成的最大数值(0表示该区间无法合并)
    int dp[300][300]={};
    
    int main(){
        // 问题分析:区间DP问题,合并相邻两个相同的数(合并后数值+1),求能得到的最大数字
        // 解题步骤:1.初始化单个数字的区间(无法合并,值为数字本身);2.按区间长度从小到大动态规划,枚举分割点判断左右子区间能否合并;
        //          3.若左右子区间能合并成相同数值,则当前区间合并后的值为子区间值+1;4.遍历所有区间找到最大值输出
        
        cin>>n;
        for(int i=1;i<=n;i++) cin>>arr[i];  // [3] 读取输入的n个数字
        
        // 1. 初始化:长度为1的区间(单个数字无法合并,值为数字本身)
        for(int i=1;i<=n;i++) dp[i][i]=arr[i];
    
        // 区间DP核心循环:按区间长度从小到大计算(len为区间长度,从2到n)
        for(int len=2;len<=n;len++){
            // 遍历所有长度为len的区间的左端点l
            for(int l=1;l+len-1<=n;l++){
                int r=l+len-1;  // [4] 计算当前区间的右端点r
                
                // 枚举分割点i,将区间[l, r]分为[l, i]和[i+1, r]两个子区间
                for(int i=l;i<r;i++){
                    // 判断两个子区间能否合并:子区间的合并值不为0(能合并)且两个子区间的合并值相等
                    if(dp[l][i]!=0 && dp[i+1][r]!=0 && dp[l][i]==dp[i+1][r]){
                        // 合并后的值为子区间值+1,更新当前区间的合并值
                        dp[l][r]=dp[l][i]+1;
                    }	
                } 
            }
        }
        
        // 遍历所有区间,找到能合并出的最大数值
        int a=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                a=max(dp[i][j],a);  // [5] 取所有区间合并值的最大值
            }
        }
        cout<<a;  // [6] 输出能得到的最大数字
        return 0;
    }
    
    • 1

    信息

    ID
    1345
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者