区间DP求调
查看原帖
区间DP求调
638718
xueruo楼主2022/12/3 10:02

第一个答案总是会大一点

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n,a[40010],f1[5010][5010],f2[5010][5010],s[40010];
//f1[l][r]表示从l到r合并的最小代价
//f2[l][r]表示从l到r合并的最大代价
//s为前缀和
//先用k切成2部分,[l][k]和[k+1][r]
//f1[l][k]+f1[k+1][r]+s[r]-s[l-1]->取最小值f1[l][r]
//f2[l][k]+f2[k+1][r]+s[r]-s[l-1]->取最大值f2[l][r]
int main(){
	ios::sync_with_stdio(false),cin.tie(),cout.tie();
	cin>>n;
	memset(f1,0x3f3f,sizeof(f1));
	memset(f2,0,sizeof(f2));
	for(int i=1;i<=n;i++){
		cin>>a[i];
		f1[i][i]=0;
		f2[i][i]=0;
		s[i]=s[i-1]+a[i];
	}
	for(int len=2;len<=n;len++){
		for(int l=1;l+len-1<=n;l++){
			int r=l+len-1;
			for(int k=l;k<r;k++){
				f1[l][r]=min(f1[l][r],f1[l][k]+f1[k+1][r]+s[r]-s[l-1]);
			}
		}
	}
	for(int len=2;len<=n;len++){
		for(int l=1;l+len-1<=n;l++){
			int r=l+len-1;
			for(int k=l;k<r;k++){
				f2[l][r]=max(f2[l][r],f2[l][k]+f2[k+1][r]+s[r]-s[l-1]);
			}
		}
	}
	cout<<f1[1][n]<<endl<<f2[1][n];
	return 0;
}
/*
in
4
4 5 9 4
out
43
54
*/
2022/12/3 10:02
加载中...