题解 P4767 【[IOI2000]邮局】
Problem
题意
有
题解
这个题的
再考虑
当
再证明
假设四边形不等式对该式成立,并且
若要使
即使
根据以上归纳假设,得:
比较
证毕。
最后证明
证明
在不等式两边添加一定的项试图得到
移项可得:
则说明对于所有的
对于
Code
#include <bits/stdc++.h>
using namespace std;
const int SIZE = 3000 + 5;
const int inf = 0x7f7f7f7f;
int n, p;
int a[SIZE], sum[SIZE], f[SIZE][SIZE], k[SIZE][SIZE];
inline int read()
{
char ch = getchar();
int f = 1, x = 0;
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); }
return x * f;
}
inline int Calc(int x, int y)
{
int Mid = (x + y) >> 1;
return sum[y] - sum[Mid] - (y - Mid) * a[Mid] + (Mid - x) * a[Mid] - sum[Mid - 1] + sum[x - 1];
}
int main()
{
n = read(), p = read();
for (int i = 1; i <= n; i++)
{
a[i] = read();
sum[i] = sum[i - 1] + a[i];
}
for (int i = 0; i <= n; i++)
f[i][i] = 0, k[i][i] = i;
for (int len = 1; len <= n - p; len++)
{
int j = 0;
for (int i = 0; (j = i + len) <= n; i++)
f[i][j] = inf;
for (int i = 1; (j = i + len) <= n; i++)
{
for (int K = k[i][j - 1]; K <= k[i + 1][j]; K++)
{
int t = f[i - 1][K - 1] + Calc(K, j);
if (t < f[i][j])
{
f[i][j] = t;
k[i][j] = K;
}
}
}
}
printf("%d", f[p][n]);
return 0;
}