本文参考了洛谷某大佬的文章,查看原文的话请点击此处。。
里面有些讲的我觉着不大好的,在这里给大家补充一下:
首先,他里面提到的f[i][j]的定义出了问题,并不是指关闭了i~j之间的灯之后剩余的灯的总功率(sum:那你还要我有何用),而是指关闭f[i][j]之间的所有灯花费的最小电量,所以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++)
l指的是左右端点的距离(也就是j-i),而i就是枚举左端点
最后附上注释代码一份:
#include <cstdio>#include <cstring>
int f[60][60][2];
int n,m;
int sum[60],a[60];
int minn(int x,int y){return x<y?x:y;}//据说手打min会更快
int main()
{
scanf("%d %d",&n,&m);
sum[0]=0;
memset(f,127,sizeof(f));//初始化,否则会出问题
for(int i=1;i<=n;i++)
{
int x;
scanf("%d %d",&a[i],&x);
sum[i]=sum[i-1]+x;//记录前i盏灯的总功效
}
f[m][m][0]=f[m][m][1]=0;//瞬间关掉自己初始位置的灯
for(int k=2;k<=n;k++)
{
for(int i=1;i<=n-k+1;i++)
{
int j=i+k-1;
f[i][j][0]=minn(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][0]一定是由f[i+1][j][0]或f[i+1][j][1]时的状态走来的,只需要用已经耗去的电量加上
//(到达f[i][j][0]所用的时间)*(未关掉的灯的每秒消耗的电量)就可以得到f[i][j][0]了
f[i][j][1]=minn(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]));//同上
}
}
printf("%d",minn(f[1][n][0],f[1][n][1]));
}