题意:某一村庄在一条路线上安装了
一道区间 DP 问题,有点难想。
老张在每次关灯后,他可以选择一条路走到底,把后面的灯关完,也可以选择调头,先把这边的灯关掉,关键在走哪边能使耗电最小。
然后我们可以推出状态:
现在考虑其中
然后就得到了状态转移方程:
其中
类似的,得到:
最后由于不知道老张会在左端点还是右端点结束,所以答案为
然后初始化是
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int n,c;
int a[55],b[55];
int sum[55],f[55][55][2];
int main()
{
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
sum[i]=sum[i-1]+b[i];
}
memset(f,0x3f,sizeof(f));
f[c][c][0]=f[c][c][1]=0;
for(int l=1;l<n;l++)
for(int i=1;i+l<=n;i++)
{
int j=i+l;
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][1]+(a[j]-a[j-1])*(sum[i-1]+sum[n]-sum[j-1]),f[i][j-1][0]+(a[j]-a[i])*(sum[i-1]+sum[n]-sum[j-1]));
}
int ans=min(f[1][n][1],f[1][n][0]);
printf("%d",ans);
return 0;
}