区间DP搬石子

 这题比较特殊,石头按照环形放置

首位相接把数组复制两次就好了

最后枚举一下就行

#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxn = 300;
ll mx[maxn][maxn];
ll mi[maxn][maxn];
int list[maxn];
ll cns[maxn];

int main(){
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&list[i]);
		list[n+i] = list[i];
	}
	for(int i=1;i<=2*n;i++){
		cns[i] += cns[i-1] + list[i];
	}
	for(int len = 2;len<=2*n;len++){
		for(int l = 1;l<=2*n - len + 1;l++){
			
			int r = l+len - 1;
			mi[l][r] = 1e15;
			
			for(int k = l;k<r;k++){
				mi[l][r] = min(mi[l][r],mi[l][k] + mi[k+1][r]);
				
				mx[l][r] = max(mx[l][r],mx[l][k] + mx[k+1][r]);
			}
			mi[l][r] += cns[r] - cns[l-1];
			mx[l][r] += cns[r] - cns[l-1];
		}
	}
	ll a = 1e16;
	ll b = -1;
	for(int i=1;i<=n;i++){
		a = min(a,mi[i][i+n-1]);
		b = max(b,mx[i][i+n-1]);
	}
	printf("%lld\n%lld\n",a,b);
	return 0;
} 

  

猜你喜欢

转载自www.cnblogs.com/lesning/p/12359668.html