Luogu 1220 关路灯
一道区间 DP
#include<bits/stdc++.h>
using namespace std;
const int N=51;
int n,c;
int w[N],a[N];
int f[N][N][2],s[N];
//f[i,j,0/1] 关 [i,j] 的灯,现在在左 / 右端点的位置
//s 表示功率的前缀和,转移的时候用于累加新消耗的功率
// 目标:min(f[1][n][0],f[1][n][1])
int main(){scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i],&w[i]),s[i]=s[i-1]+w[i];
memset(f,0x3f,sizeof(f));
f[c][c][0]=f[c][c][1]=0;
for(int k=1;k<=n;k++){for(int i=1;i+k<=n;i++){
int j=i+k;
//f[i][j][0]
f[i][j][0]=min(f[i+1][j][0]+(s[n]-s[j]+s[i])*(a[i+1]-a[i]),
f[i+1][j][1]+(s[n]-s[j]+s[i])*(a[j]-a[i])
);
f[i][j][1]=min(f[i][j-1][0]+(s[n]-s[j-1]+s[i-1])*(a[j]-a[i]),
f[i][j-1][1]+(s[n]-s[j-1]+s[i-1])*(a[j]-a[j-1])
);
}
}
printf("%d",min(f[1][n][0],f[1][n][1]));
return 0;
}