P1880 [NOI1995]石子合并(环形区间)
和上一个题目相似,只不过这个变成了环形的,那么我们确定区间的时候就需要把长度变成2×n这样的话我们的集合才能包含所有的情况。
#include<bits/stdc++.h>
using namespace std;
const int N=6e2+5;
int f[N][N],f1[N][N],a[N],sum[N];
int main()
{
int n; cin>>n;
memset(f,0x3f3f3f3f,sizeof f);
memset(f1,-0x3f3f3f3f,sizeof f1);
for(int i=1;i<=n;i++){
cin>>a[i];
a[i+n]=a[i];
}
for(int i=1;i<=n*2;i++) sum[i]=sum[i-1]+a[i];
for(int len=1;len<=n;len++){
for(int l=1;l+len-1<=n*2;l++){
int r=len+l-1;
if(len==1) f[l][r]=f1[l][r]=0;
for(int k=l;k<=r;k++){
f[l][r]= min(f[l][r],f[l][k]+f[k+1][r]+(sum[r]-sum[l-1]));
f1[l][r]=max(f1[l][r],f1[l][k]+f1[k+1][r]+(sum[r]-sum[l-1]));
}
}
}
int maxv=-0x3f3f3f3f,minv=0x3f3f3f3f;
for(int i=1;i<=n;i++){
maxv=max(f1[i][i+n-1],maxv);
minv=min(f[i][i+n-1],minv);
}
cout<<minv<<endl<<maxv<<endl;
}