Loading

P1220 关路灯 区间DP

P1220 关路灯 区间DP

题意

道路上有\(n\)盏灯,每盏灯有两个属性,坐标和功率。

老张的速度为\(1m/s\)

初始给出老张在第几盏灯。

当到达某盏灯时 老张可以花费\(0\) 秒关掉一盏灯,确定一种路线使所有灯的耗能最小。

\[n \leq 50,1\leq c \leq n \]

分析

\(f[i][j]\)表示从\(i\)\(j\) 关掉 所有灯的总耗能。

那么进一步考虑,令\(f[i][j][0]\) 表示关掉\(i\)\(j\)的灯后,老张站在\(i\)点。

\(f[i][j][1]\) 表示关掉\(i\)\(j\)后,老张站在\(j\)点。

那么考虑状态转移。

\[f[i][j][0] = min(f[i + 1][j][0] + (a[i + 1] - a[i]) \times (sum[i] + sum[n] - sum[j]), \\f[i + 1][j][1] + (a[j] - a[i]) \times (sum[i] + sum[n] - sum[j])); \]

同理可以得到\(f[i][j][1]\)

这里注意初始化

代码

int a[55];
int b[55];
int sum[55];
int f[55][55][2];
int main() {
    int n = readint();
    int c = readint();
    memset(f, 0x3f, sizeof f);
    for (int i = 1; i <= n; i++)
        a[i] = readint(), b[i] = readint(), sum[i] = sum[i - 1] + b[i];
    f[c][c][0] = f[c][c][1] = 0;
    for(int l = 2;l <= n;l++)
        for (int i = 1; i + l - 1 <= n; i++) {
            int j = i + l - 1;
            f[i][j][0] = min(f[i + 1][j][0] + (a[i + 1] - a[i]) * (sum[i] + sum[n] - sum[j]), f[i + 1][j][1] + (a[j] - a[i]) * (sum[i] + sum[n] - sum[j]));
            f[i][j][1] = min(f[i][j - 1][0] + (a[j] - a[i]) * (sum[i - 1] + sum[n] - sum[j - 1]), f[i][j - 1][1] + (a[j] - a[j - 1]) * (sum[i - 1] + sum[n] - sum[j - 1]));
        }
    int ans = min(f[1][n][0], f[1][n][1]);
    cout << ans;
}
posted @ 2020-09-18 13:31  MQFLLY  阅读(119)  评论(0编辑  收藏  举报