练dp练烦了,突发奇想写了一个记忆化搜索,大致思路是把原来的线性末尾再补一节一样的,对这两段求合并代价。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define endl '\n'
using namespace std;
using ll=long long;
using PII=pair<int,int>;
const int N=410;
int t;
int dmax[N][N],dmin[N][N];

vector<ll>pre(N+1);
vector<int>a(N+1);
ll deal1(int l,int r){
	if(l==r)return 0;
	else if(dmax[l][r]!=0)return dmax[l][r];
	else{
		ll cnt=0;
        rep(i,l+1,r){
           cnt=max(deal1(l,i-1)+deal1(i,r)+pre[r]-pre[l-1],cnt);
		}
		dmax[l][r]=cnt;
        return cnt;
	}
}
ll deal2(int l,int r){
	if(l==r)return 0;
	else if(dmin[l][r]!=0)return dmin[l][r];
	else{
		ll cnt=0x4f4f4f4f;
        rep(i,l+1,r){
           cnt=min(deal2(l,i-1)+deal2(i,r)+pre[r]-pre[l-1],cnt);
		}
		dmin[l][r]=cnt;
        return cnt;
	}

}
void solve(){
	
    int n;cin>>n;
	rep(i,1,n)cin>>a[i];
	rep(i,n+1,n*2)a[i]=a[i-n];
	rep(i,1,n*2)pre[i]=pre[i-1]+a[i];
	ll ans1=0,ans2=0x4f4f4f4f;
	rep(i,1,n){
		ans2=min(ans2,deal2(i,i+n-1));
		ans1=max(ans1,deal1(i,i+n-1));
	}
    cout<<ans2<<endl<<ans1;


}
int main(){
	ios::sync_with_stdio(false),cin.tie(0);
	int t=1;
	while(t--){
		solve();
	}
	return 0;
}