{ d p m i n [ l ] [ r ] = m i n ( d p m i n [ l ] [ r ] , d p m i n [ l ] [ k ] + d p m i n [ k + 1 ] [ r ] ) + ∑ i = l i ≤ r a [ i ] ; d p m a x [ l ] [ r ] = m a x ( d p m a x [ l ] [ r ] , d p m a x [ l ] [ k ] + d p m a x [ k + 1 ] [ r ] ) + ∑ i = l i ≤ r a [ i ] ; \begin{dcases} dpmin[l][r] = min(dpmin[l][r], dpmin[l][k] + dpmin[k+1][r]) + \sum_{i = l}^{i \leq r} a[i];\\[2ex] dpmax[l][r] = max(dpmax[l][r], dpmax[l][k] + dpmax[k+1][r]) + \sum_{i = l}^{i \leq r} a[i]; \end{dcases} ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧dpmin[l][r]=min(dpmin[l][r],dpmin[l][k]+dpmin[k+1][r])+i=l∑i≤ra[i];dpmax[l][r]=max(dpmax[l][r],dpmax[l][k]+dpmax[k+1][r])+i=l∑i≤ra[i];
先贴一波大佬的博客
首先给出正确的 O ( n 3 ) O(n^3) O(n3)代码
#include
#include
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for (int i = (a); i >= (b); --i)
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rof(i, a, b) for (int i = (a); i > (b); --i)
#define ll long long
#define db double
#define oo 0x3f3f3f3f
#define eps 0.00001
#define all(x) x.begin(), x.end()
#define met(a, b) memset(a, b, sizeof(a))
#define id(x) ((x + 8))
#define what_is(x) cerr << #x << " is " << x << endl
#define lowbit(x) x &(-x)
using namespace std;
const int maxn = 2e3 + 9;
const int mod = 1e6 + 3;
int dpmin[maxn][maxn], n, a[maxn], dpmax[maxn][maxn], sum[maxn];
int main()
{
ios::sync_with_stdio(0);
int n;
cin >> n;
met(dpmin, oo);
_rep(i, 1, n)
{
cin >> a[i];
a[i + n] = a[i];
dpmin[i][i] = dpmin[i + n][i + n] = 0;
}
_rep(i, 1, 2*n){
sum[i] = sum[i-1] + a[i];
}
_rep(len, 2, n)
{
_rep(l, 1, 2 * n - len + 1)
{
int r = l + len - 1;
_rep(k, l, r-1){
dpmax[l][r] = max(dpmax[l][k] + dpmax[k+1][r] + sum[r] - sum[l-1], dpmax[l][r]);
dpmin[l][r] = min(dpmin[l][k] + dpmin[k+1][r] + sum[r] - sum[l-1], dpmin[l][r]);
}
}
}
int min_val = oo, max_val = 0;
_rep(i, 1, n)
{
min_val = min(dpmin[i][i + n - 1], min_val);
max_val = max(max_val, dpmax[i][i + n - 1]);
}
cout << min_val << endl
<< max_val << endl;
}
#include
#include
#include
#include
#include
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for (int i = (a); i >= (b); --i)
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rof(i, a, b) for (int i = (a); i > (b); --i)
#define ll long long
#define db double
#define oo 0x3f3f3f3f
#define eps 0.00001
#define all(x) x.begin(), x.end()
#define met(a, b) memset(a, b, sizeof(a))
#define id(x) ((x + 8))
#define what_is(x) cerr << #x << " is " << x << endl
#define lowbit(x) x &(-x)
using namespace std;
const int maxn = 2e3 + 9;
const int mod = 1e6 + 3;
int dpmin[maxn][maxn], n, a[maxn], dpmax[maxn][maxn], sum[maxn], kma[maxn][maxn], kmi[maxn][maxn];
int main()
{
ios::sync_with_stdio(0);
int n;
cin >> n;
met(dpmin, oo);
_rep(i, 1, n)
{
cin >> a[i];
a[i + n] = a[i];
dpmin[i][i] = dpmin[i + n][i + n] = 0;
}
_rep(i, 1, 2 * n) {
sum[i] = sum[i - 1] + a[i];
kmi[i][i] = kma[i][i] = i;
}
_rep(len, 2, n)
{
_rep(l, 1, 2 * n - len + 1)
{
int r = l + len - 1;
_rep(k, l, r - 1) {
/*dpmax[l][r] = max(dpmax[l][k] + dpmax[k + 1][r] + sum[r] - sum[l - 1], dpmax[l][r]);
dpmin[l][r] = min(dpmin[l][k] + dpmin[k + 1][r] + sum[r] - sum[l - 1], dpmin[l][r]);*/
if (dpmax[l][k] + dpmax[k + 1][r] + sum[r] - sum[l - 1] > dpmax[l][r]) {
dpmax[l][r] = dpmax[l][k] + dpmax[k + 1][r] + sum[r] - sum[l - 1];
kma[l][r] = k;
}
if (dpmin[l][k] + dpmin[k + 1][r] + sum[r] - sum[l - 1] < dpmin[l][r]) {
dpmin[l][r] = dpmin[l][k] + dpmin[k + 1][r] + sum[r] - sum[l - 1];
kmi[l][r] = k;
}
}
}
}
_rep(i, 1, n + 1) {
_rep(j, i+1, i + n-1) {
assert(kma[i][j - 1] <= kma[i][j] && kma[i][j] <= kma[i + 1][j]);
//assert(kmi[i][j - 1] <= kmi[i][j] && kmi[i][j] <= kmi[i + 1][j]);
}
}
}
但是对于dpmax有一个性质, 对于某dpmax[l][r], 只有k = l或者k = r-1时最大
其实最小也有性质, 当k在l和r中间的时候也能取最小
#include
#include
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for (int i = (a); i >= (b); --i)
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rof(i, a, b) for (int i = (a); i > (b); --i)
#define ll long long
#define db double
#define oo 0x3f3f3f3f
#define eps 0.00001
#define all(x) x.begin(), x.end()
#define met(a, b) memset(a, b, sizeof(a))
#define id(x) ((x + 8))
#define what_is(x) cerr << #x << " is " << x << endl
#define lowbit(x) x &(-x)
using namespace std;
const int maxn = 2e3 + 9;
const int mod = 1e6 + 3;
int dpmin[maxn][maxn], n, a[maxn], dpmax[maxn][maxn], sum[maxn], s[maxn][maxn] ; //s[i][j]存储dpmin[i][j]的最优解k
int main()
{
ios::sync_with_stdio(0);
int n;
cin >> n;
met(dpmin, oo);
_rep(i, 1, n)
{
cin >> a[i];
a[i + n] = a[i];
dpmin[i][i] = dpmin[i + n][i + n] = 0;
}
_rep(i, 1, 2 * n)
{
sum[i] = sum[i - 1] + a[i];
s[i][i] = i;
}
_rep(len, 2, n)
{
_rep(l, 1, 2 * n - len + 1)
{
int r = l + len - 1;
dpmax[l][r] = max(dpmax[l+1][r]+dpmax[l][l], dpmax[l][r-1]+dpmax[r][r]) + sum[r] - sum[l-1];
int K, tmp = oo;
_rep(k, s[l][r-1], s[l+1][r]){
int tt = dpmin[l][k] + dpmin[k+1][r] + sum[r] - sum[l-1];
if(tt < tmp){
tmp = tt;
K = k;
}
}
s[l][r] = K;
dpmin[l][r] = tmp;
}
}
int min_val = oo, max_val = 0;
_rep(i, 1, n)
{
min_val = min(dpmin[i][i + n - 1], min_val);
max_val = max(max_val, dpmax[i][i + n - 1]);
}
cout << min_val << endl
<< max_val << endl;
}