P1880 [NOI1995]石子合并
把环*2转成链就和n个石子放一排的石子合并一样了。
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ls rt<<1 #define rs (rt<<1)+1 #define ll long long #define fuck(x) cout<<#x<<" "<<x<<endl; const int maxn=1e6+10; int d[4][2]={1,0,-1,0,0,1,0,-1}; int dp1[205][205],dp2[205][205]; int a[205],sum[maxn]; int main(){ int n; cin>>n; for(int i=1;i<=n;i++) scanf("%d",&(a[i])),sum[i]=sum[i-1]+a[i]; for(int i=n+1;i<=2*n;i++) a[i]=a[i-n],sum[i]=sum[i-1]+a[i]; for(int len=2;len<=n;len++) for(int i=1;i<=2*n-len+1;i++){ int j=i+len-1; dp1[i][j]=-inf; dp2[i][j]=inf; for(int k=i;k<j;k++) dp1[i][j]=max(dp1[i][k]+dp1[k+1][j]+sum[j]-sum[i-1],dp1[i][j]),dp2[i][j]=min(dp2[i][k]+dp2[k+1][j]+sum[j]-sum[i-1],dp2[i][j]); } int maxx=-inf,minn=inf; for(int i=1;i<=n+1;i++) maxx=max(maxx,dp1[i][i+n-1]),minn=min(minn,dp2[i][i+n-1]); cout<<minn<<endl<<maxx<<endl; return 0; }