Codeforces 1312E. Array Shrinking

Posted zxytxdy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

以上是关于Codeforces 1312E. Array Shrinking的主要内容,如果未能解决你的问题,请参考以下文章

E Minimum Array ( Codeforces Round #555 (Div. 3) )

Codeforces 402D Upgrading Array:贪心 + 数学

Powerful array CodeForces - 86D(莫队)

codeforces 1312E

Codeforces 1312D. Count the Arrays

Codeforces 837E. Vasya's Function