区间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;
}
寻找真正的热爱

浙公网安备 33010602011771号