DP学习
看题面,我们可以考虑如何暴力DP
我们可以将1~ n 的关灯顺序缩小到一个区间
并且满足无后效性
我们每次决策都要考虑向左或向右
所以需要一个状态记录在区间的左或右
我们可以得到f[i][j][1/0] 表示在 i 到 j 区间内在左 右端点时消耗电
/***********************************************************
> File Name: LGP1220.cpp
> Author: lan_m
> QQ: 2867930696
> Created Time: 2021/9/10 14:47:01
> fighting for night
*******************************************************/
#include <bits/stdc++.h>
using namespace std;
int n,s;
int di[60],po[60];
int vis[60];
int answer = 0x3f3f3f3f;
int f[60][60][3];
int sum[60];
int main() {
scanf("%d%d",&n,&s);
for (int i = 1;i <= n;i ++) {
scanf("%d%d",&di[i],&po[i]);
sum[i] = sum[i-1] + po[i];
}
memset(f,0x3f,sizeof(f));
f[s][s][0] = f[s][s][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] + (di[i+1] - di[i]) * (sum[i] + sum[n] - sum[j]) , f[i+1][j][1] + (di[j] - di[i]) * (sum[i] + sum[n] - sum[j]));
f[i][j][1] = min(f[i][j-1][0] + (di[j] - di[i]) * (sum[i-1] + sum[n] - sum[j-1]),f[i][j-1][1] + (di[j] - di[j-1]) * (sum[i-1] + sum[n] - sum[j-1]));
}
}
answer = min(f[1][n][0],f[1][n][1]);
printf ("%d",answer);
return 0;
}