ybt1675塔

1675:塔

时间限制: 1000 ms 内存限制: 262144 KB

【题目描述】

你有\(N\)座塔一列排开。每座塔各自有高度,有可能相等。

你每次可以选择相邻的两座塔合并在一起,即这两座塔的高度叠加后变成了同一座塔。然后原本分别与这两座塔相邻的塔变得与这座新的塔相邻。

你的目标是使用最少的操作次数在游戏的最后获得一列塔,这些塔的高度从左到右形成一个不下降的数列。

【输入】

第一行一个整数\(N\)

第二行\(N\)个整数,从左到右描述塔的高度。

【输出】

仅一个整数表示最少的操作次数。

【输入样例】

5
8 2 7 3 1

【输出样例】

3

【数据规模】

对于30%的数据,\(N≤10\)

对于60%的数据,\(N,A_i≤200\)

对于100%的数据,\(1≤N,A_i≤3000\)


动态规划。据说可以单调优化,以后再说……
f[i]:前i个塔单调不下降最少的操作次数
mn[i]:对应f[i]的最后一个的高度
f[n]就是答案了


#include<bits/stdc++.h>
using namespace std;
const int maxn=3010;
int n,sz[maxn];
int f[maxn],mn[maxn];

int main()
{
	scanf("%d",&n);
	for(int a,i=1;i<=n;++i)scanf("%d",&a),sz[i]=sz[i-1]+a;
	memset(f,0x7f,sizeof f);f[0]=0;
	for(int i=1;i<=n;++i)
	{
		for(int j=i-1;j>=0;--j)
			if(sz[i]-sz[j]>=mn[j])
				if(f[j]+i-j-1<f[i])
				{
					f[i]=f[j]+i-j-1;
					mn[i]=sz[i]-sz[j];
				}
	}
	cout<<f[n]<<endl;
	return 0;
}

posted on 2024-12-24 14:42  gryzy  阅读(3)  评论(0编辑  收藏  举报

导航