合并石子(环形版)
环形版相当于把链条剪段就行,代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int inf=1<<30; const int maxn=310; int s[maxn*2],f[maxn][maxn],n,fx[maxn][maxn]; int main() { freopen("stone2.in","r",stdin); freopen("stone2.out","w",stdout); scanf("%d",&n); int x; for(int i=1;i<=n;i++) { scanf("%d",&x); s[i]=s[i-1]+x; f[i][i]=0; fx[i][i]=0; } for(int i=1;i<n;i++) s[i+n]=s[i]+s[n]; for(int l=1;l<=n;l++) for(int i=1;i<n*2;i++) { int j=i+l; f[i][j]=inf; if(j>=2*n) break; for(int k=i;k<j;k++) { f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]); fx[i][j]=max(fx[i][j],fx[i][k]+fx[k+1][j]+s[j]-s[i-1]); } } int ans=inf,ansmax=0; for(int i=1;i<=n;i++) { ans=min(ans,f[i][i+n-1]); ansmax=max(ansmax,fx[i][i+n-1]);//输出的这个部分需要考虑考虑 } printf("%d\n%d",ans,ansmax); }