P1220 关路灯
P1220 关路灯
区间 \(DP\) , 设 \(f[i][j][0/1]\) 表示关完 \([i, j]\) 的灯后在左/右边的最小值, 然后我们枚举 \(i\) 和 \(j\) , 用 \(f[i][j][0/1]\) 更新状态 \(f[i - 1][j][0/1]\) 和 \(f[i][j + 1][0/1]\) .
\(code:\)
#include <bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') f = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
const int N = 55;
int n, c, pos[N], cost[N], sum[N], f[N][N][2];
int main () {
n = read(), c = read();
memset(f, 0x3f, sizeof(f)); f[c][c][1] = f[c][c][0] = 0;
for (int i = 1; i <= n; i++) {
pos[i] = read(), cost[i] = read();
sum[i] = sum[i - 1] + cost[i];
}
for (int i = c; i >= 1; i--) {
for (int j = c; j <= n; j++) {
int cost1 = sum[n] - sum[j] + sum[i - 1];
if (i > 1) {
f[i - 1][j][0] = min(f[i][j][0] + (pos[i] - pos[i - 1]) * cost1, f[i][j][1] + (pos[j] - pos[i - 1]) * cost1);
f[i - 1][j][1] = min(f[i - 1][j][1], f[i - 1][j][0] + (pos[j] - pos[i - 1]) * (cost1 - cost[i - 1]));
}
if (j < n) {
f[i][j + 1][1] = min(f[i][j][1] + (pos[j + 1] - pos[j]) * cost1, f[i][j][0] + (pos[j + 1] - pos[i]) * cost1);
f[i][j + 1][0] = min(f[i][j + 1][0], f[i][j + 1][1] + (pos[j + 1] - pos[i]) * (cost1 - cost[j + 1]));
}
}
}
printf("%d", min(f[1][n][0], f[1][n][1]));
return 0;
}
一定要初始化...因为没初始化卡了好久...
看不见我看不见我看不见我