# [HDU 3506]Monkey Party

## Description

$1\leq n\leq 1000$

## Solution

• 四边形不等式，还是以 $\forall a,b,c,d, a\leq b\leq c\leq d, w(a,d)+w(b,c)\geq w(a,c)+w(b,d)$ 为例。
• 区间单调性，即 $\forall a,b,c,d, a\leq b\leq c\leq d, w(a,d)\geq w(b,c)$，即小区间的函数值不超过包含其的大区间。并且式中的不等号应时刻与四边形不等式的不等号方向一致。

$l=1$，$(l,l+\delta-1)$ 枚举长度是 $s_{l+1,l+\delta-1}-s_{l,l+\delta-2}=s_{2,\delta}-s_{1,\delta-1}$；
$l=2$，枚举长度是 $s_{3,1+\delta}-s_{2,\delta}$；
$l=3$，枚举长度是 $s_{4,2+\delta}-s_{3,1+\delta}$；
$\vdots$
$l=n+1-\delta$，枚举长度是 $s_{n+2-\delta,n}-s_{n+1-\delta,n-1}$。

## Code

#include <bits/stdc++.h>
#define ll long long
#define w(l, r) (a[r]-a[l-1])
using namespace std;
const int N = 2005;

int n, a[N], s[N][N];
ll f[N][N];

int main() {
while (~scanf("%d", &n)) {
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]), a[i+n] = a[i];
n <<= 1;
for (int i = 1; i <= n; i++) a[i] += a[i-1];
for (int i = 1; i <= n; i++)
f[i][i] = 0, s[i][i] = i;
for (int i = 2, m = n>>1; i <= m; i++)
for (int l = 1, r; (r = l+i-1) <= n; l++) {
f[l][r] = 1e15;
for (int k = s[l][r-1]; k <= s[l+1][r]; k++)
if (k < r && f[l][r] > f[l][k]+f[k+1][r]+w(l, r)) {
f[l][r] = f[l][k]+f[k+1][r]+w(l, r);
s[l][r] = k;
}
}
ll ans = 1e15;
for (int i = 1, m = n>>1; i <= m; i++)
ans = min(ans, f[i][i+m-1]);
printf("%lld\n", ans);
}
return 0;
}
posted @ 2020-08-06 01:22  NaVi_Awson  阅读(101)  评论(0编辑  收藏  举报