记录编号 323777 评测结果 AAAAAAA
题目名称 [HZOI 2014] 合并石子 最终得分 100
用户昵称 GravatarGo灬Fire 是否通过 通过
代码语言 C++ 运行时间 0.005 s
提交时间 2016-10-17 07:12:37 内存使用 11.97 MiB
显示代码纯文本
/*
	Name: 合并石子 
	区域动归  优化求最大最小的模板  合并石子
	From:http://cogs.pw/cogs/problem/problem.php?pid=1658 
	Author: Go灬Fire 
	Date: 17/10/16 07:09
	Description: 合并类动态规划,虽然不优化可以过,但是优化有两个
				1) 求合并的最小代价,定义g[i][j]记录断点,即上一个最优解产生的位置,k便从g[i][j-1]到g[i+1][j],优化许多
				2)  求合并的最大代价,四边形不等式,f[i][j]=max(f[i+1][j],f[i][j-1])+sum[j]-sum[i-1]; 
*/
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define Begin freopen("stone2.in","r",stdin);freopen("stone2.out","w",stdout);
#define End fclose(stdin);fclose(stdout);
using namespace std;
const int maxn=1010;
int n,sum[maxn],f[maxn][maxn][2],g[maxn][maxn];
void Init();

int main(){
    Begin
    Init();
    End
    //system("pause");
    return 0;
}
void Init(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&sum[i]),sum[i+n]=sum[i],g[i][i]=i,sum[i]+=sum[i-1];
	for(int i=n+1;i<=2*n;i++)sum[i]+=sum[i-1],g[i][i]=i;
	for(int d=2;d<=n;d++){
		for(int i=1;i<=2*n-d+1;i++){
			int j=i+d-1;
			f[i][j][0]=max(f[i+1][j][0],f[i][j-1][0])+sum[j]-sum[i-1];
			f[i][j][1]=1e9;
			for(int k=g[i][j-1];k<=g[i+1][j];k++){
				if(f[i][j][1]>f[i][k][1]+f[k+1][j][1]+sum[j]-sum[i-1]){
					f[i][j][1]=f[i][k][1]+f[k+1][j][1]+sum[j]-sum[i-1];
					g[i][j]=k;
				}
			}
		}
	}
	int _max=0,_min=1e9;
	for(int i=1;i<=n;i++){
		_max=max(_max,f[i][n+i-1][0]);
		_min=min(_min,f[i][n+i-1][1]);
	}
	printf("%d\n%d",_min,_max);
}