• Codeforces 1312E. Array Shrinking


    Codeforces 1312E. Array Shrinking

    题意:

    有一个序列,你可以选择一对相邻的数字(a_i=a_{i+1}),然后将这两个数字换为(a_i+1)

    问最后最少能留下多少个数字。

    思路:

    似乎没有好的贪心策略,所以确定是dp应该没问题。

    我们设(g(i,j))表示在区间([i,j])范围内的那个相同的数字是什么。

    那么我们可以用区间dp的方式预处理一下(g)

    当然在预处理的过程中要记录下所有区间的信息。

    (f(i))表示前(i)个数字的答案,然后枚举所有区间信息更新答案就好了。

    还是看代码吧。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 500+10;
    int g[maxn][maxn];
    
    struct Node{
        int l, r;
    }p[maxn*maxn];
    bool cmp(Node a, Node b){
        return a.r < b.r;
    }
    int tot;
    
    int n;
    int f[maxn];
    
    int main()
    {
        scanf("%d", &n);
        for(int i = 1, x; i <= n; i++)
        {
            scanf("%d", &x);
            g[i][i] = x;
            p[++tot] = {i, i};
        }
        for(int len = 2; len <= n; len++)
            for(int l = 1; l <= n-len+1; l++)
        {
            int r = len+l-1;
            for(int k = l; k < r; k++)
            if(g[l][k]&&g[k+1][r]&&g[l][k]==g[k+1][r])
            {
                g[l][r] = g[l][k]+1;
                p[++tot] = {l, r};
                break;
            }
        }
    
        sort(p+1, p+1+tot, cmp);
        for(int i = 1, j = 1; i <= n; i++)
        {
            f[i] = i;
            while(p[j].r == i)
            {
                f[i] = min(f[i], f[p[j].l-1]+1);
                j++;
            }
        }
        //for(int i = 1; i <= tot; i++)
        //printf("%d %d
    ", p[i].l, p[i].r);
    
        cout << f[n] << endl;
        return 0;
    }
    
    
  • 相关阅读:
    Zabbix学习记录
    json_encode 函数使用中报错提示缺少两个参数
    MAC 上搭建一个本地LNMP环境学习laravel(一)
    mysql root 密码重置
    phpstorm格式化代码导致模板报错
    Get 和 Post
    axios设置请求超时时间 timeout
    charles安装配置 for Mac
    让 div 的高度等于宽度,的小技巧
    Git命令行删除本地和远程分支
  • 原文地址:https://www.cnblogs.com/zxytxdy/p/12454472.html
Copyright © 2020-2023  润新知