1 条题解

  • 0
    @ 2025-10-10 20:13:35

    C++ :

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    const int maxn = 255;
    
    int n, val, ans;
    int f[maxn][maxn];
    
    inline int read(void) // 快读优化 
    {
        int s = 0, w = 1;
        char ch = getchar();
        for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') w = -1;
        for(; ch <= '9' && ch >= '0'; ch = getchar()) s= s * 10 + ch - '0';
        return s * w;
    }
    
    int main()
    {
        n = read();
        for(register int i = 1; i <= n; i++) val = read(), f[i][i] = val; // 预处理,当不进行合并时得到的价值就是自己 
        for(register int len = 2; len <= n; len++) // 枚举所合并区间的长度,因为转移是从小区间转移到大区间,所以要从小到大枚举区间的长度     
        {
            for(register int i = 1; i <= n - len + 1; i++)   // 枚举区间的左端点 ,当左端点等于  全长 减去 区间长度 再加一  的时候,右端点取到序列的最右边 
            {
                int j = i + len - 1;
             	for(register int pos = i; pos < j; pos++)    // 枚举当前区间可以由哪两个小区间转移过来 
                 {
                 	if(f[i][pos] == f[pos+1][j] && f[i][pos] != 0 && f[pos+1][j] != 0)             // 如果这两个小区间合并出的值相等,就进行转移 ,特别地,如果两个的值都是0,表示这两个区间什么也合并不出来,所以不能进行转移
                 	{
                 		f[i][j] = max(f[i][j], f[i][pos] + 1);
                 		ans = max(ans, f[i][pos] + 1);       // 用ans来保存答案 
                 		//cout<< f[i][pos] << ' ' << f[pos+1][j] << '\n'; 调试用 
                 	}
                 } 
            }
        }
        cout << ans << '\n';
        return 0;
    }
    
    • 1

    信息

    ID
    1098
    时间
    1000ms
    内存
    512MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者