正题
第四题:关路灯
这题主要就是用区间Dp(莫队可做?)。
那么一个以关灯区间的状态有两种,记录左端点和记录右端点。
我们用f[i][j][0]来表示当前是在左端点。
用f[i][j][1]来表示当前是在右端点。
一个点在左端点时,到他的状态有:f[i+1][j][1],f[i+1][j][0](从上个区间的右端点和左端点过来);
一个点在右端点时,到他的状态有:f[i][j-1][1],f[i][j-1][0](从上个区间的右端点和左端点过来);
那么当在走过来的同时,会浪费一定的电,如果当前要 求左端点,从上个区间左端点过来那么就浪费了距离乘瓦数。其他的同理,做一个前缀和a[i]来统计一下0到i的距离即可。
#include<cstdio>
#include<cstdlib>
#include<cstring>
int n,k;
struct node{int x,y;};
node s[55];
long long f[55][55][2];
int qian[55];
long long min(long long x,long long y)
{
return x<y?x:y;
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d %d",&s[i].x,&s[i].y);
qian[1]=s[1].y;
for(int i=2;i<=n;i++)
qian[i]=qian[i-1]+s[i].y;
memset(f,63,sizeof(f));
f[k][k][1]=0;
f[k][k][0]=0;
for(int l=1;l<=n-1;l++)
for(int i=1;i+l<=n;i++)
{
int j=i+l;
long long a=f[i+1][j][0]+(s[i+1].x-s[i].x)*(qian[n]-qian[j]+qian[i]);
long long b=f[i+1][j][1]+(s[j].x-s[i].x)*(qian[n]-qian[j]+qian[i]);
f[i][j][0]=min(a,min(f[i][j][0],b));;
a=f[i][j-1][0]+(s[j].x-s[i].x)*(qian[n]-qian[j-1]+qian[i-1]);
b=f[i][j-1][1]+(s[j].x-s[j-1].x)*(qian[n]-qian[j-1]+qian[i-1]);
f[i][j][1]=min(a,min(f[i][j][1],b));
}
printf("%d",min(f[1][n][0],f[1][n][1]));
}