P3080 [USACO13MAR]The Cow Run G/S题解
区间 dp。
设
为什么一定是区间捕牛?因为这片区间是走过了,牛不捕白不捕。
转移方程如下:
要排序。不然无序的不能区间 dp。
然而,初始又在哪个端点呢?只要在端点中插入一个位置为
答案是
代码实现如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 3005;
int f[N][N][2], a[N], d[N], sum[N], n, c;
int main() {
cin >> n;
for (int i = 1; i <= n; i ++)
cin >> d[i];
d[++ n] = 0, sort(d + 1, d + 1 + n);
memset(f, 0x3f, sizeof f);
c = lower_bound(d + 1, d + 1 + n, 0) - d;
f[c][c][1] = f[c][c][0] = 0;
for (int k = 2; k <= n; k ++)
for (int i = 1; i <= n; i ++) {
int j = i + k - 1;
f[i][j][0] = min(f[i + 1][j][0] + (d[i + 1] - d[i]) * (i + n - j),
f[i + 1][j][1] + (d[j] - d[i]) * (i + n - j));
f[i][j][1] = min(f[i][j - 1][0] + (d[j] - d[i]) * (i + n - j),
f[i][j - 1][1] + (d[j] - d[j - 1]) * (i + n - j));
}
cout << min(f[1][n][0], f[1][n][1]) << '\n';
return 0;
}