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(莫队)