fmax[l][r]表示合并区间[l,r]的最大分值,
fmin[l][r]表示合并区间[l,r]的最小分值
for(k l~r-1)
fmax[l][r]=max(fmax[l][r],fmax[l][k]+f[k+1][r]+sum[l][r]);
sum[l][r]可以提到外面
最小值同理
处理环形就把环搞成一个2倍长度的链,最后枚举长度为n的区间最大得分和最小得分
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 const int MAXN = 1010 ; 5 int a[MAXN],sum[MAXN],n,fmax[MAXN][MAXN],fmin[MAXN][MAXN]; 6 inline int read() 7 { 8 int x=0;char c=getchar(); 9 while(c<'0'||c>'9') c=getchar(); 10 while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar();} 11 return x; 12 } 13 int main() 14 { 15 n=read(); 16 for(register int i=1;i<=n;i++) 17 { 18 a[i]=read(); a[i+n]=a[i]; 19 } 20 for(register int i=1;i<=(n<<1);i++) 21 sum[i]=sum[i-1]+a[i]; 22 for(int i=1;i<=(n<<1);i++) 23 for(int j=1;j<=(n<<1);j++) 24 fmin[i][j]=0x7fffffff>>1; 25 for(int i=1;i<=n<<1;i++) 26 fmin[i][i]=0; 27 for(register int len=2;len<=n<<1;len++) 28 for(register int l=1;l+len-1<=n<<1;l++) 29 { 30 int r=l+len-1; 31 for(register int k=l;k<r;k++) 32 { 33 fmax[l][r]=max(fmax[l][r],fmax[l][k]+fmax[k+1][r]); 34 fmin[l][r]=min(fmin[l][r],fmin[l][k]+fmin[k+1][r]); 35 } 36 fmax[l][r]+=sum[r]-sum[l-1]; 37 fmin[l][r]+=sum[r]-sum[l-1]; 38 } 39 int ans1=0x7fffffff,ans2=0; 40 for(int i=1;i<=n;i++) 41 { 42 ans1=min(ans1,fmin[i][i+n-1]); 43 ans2=max(ans2,fmax[i][i+n-1]); 44 } 45 printf("%d %d ",ans1,ans2); 46 return 0; 47 }