我国现在能源消耗非常严重,现在政府有这样一个工作,每天早上都需要把一些路灯关掉,但是他们想让在关闭的过程中所消耗的能源是最少的,负责路灯关闭的工作人员以1m/s的速度进行行走,假设关闭路灯的时候不需要花费任何的时间,请你编写一个程序,计算在给定路灯位置和每个路灯的消耗能源的多少,求出当所有路灯关闭的时候所需要的最少能量
我国现在能源消耗非常严重,现在政府有这样一个工作,每天早上都需要把一些路灯关掉,但是他们想让在关闭的过程中所消耗的能源是最少的,负责路灯关闭的工作人员以1m/s的速度进行行走,假设关闭路灯的时候不需要花费任何的时间,请你编写一个程序,计算在给定路灯位置和每个路灯的消耗能源的多少,求出当所有路灯关闭的时候所需要的最少能量
多组测试数据循环输入
每组测试数据第一行:N表示路灯的数量 (2<=N <=1000)
第二行:V表示开始关灯的路灯号码。 (1<=V<=N)
接下来的N行中,每行包含两个用空格隔开的整数D和W,用来描述每盏灯的参数
D表示该路灯到原点的距离 (用米为单位来表示),
W表示灯泡的功率,即每秒该灯泡所消耗的能量数。(0<=D<=1000,0<=W<=1000)
路灯按照顺序给出,起始位置的那盏灯不算消耗的电能里面
输出一个整数,即消耗能量之和的最小值。
4 3 2 2 5 8 6 1 8 7
56
对于样例,我一开始在第三个路灯的位置,即在6位置
第1s的时候去5把第二盏灯关闭,消耗电能8
然后去第四盏灯,第四盏灯亮的时间是4s 所以消耗电能28
最后去关第一盏灯第一盏灯亮的时间是10s 所以消耗电能20
最后总和为8+28+20=56
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while (sc.hasNext()){
int N=sc.nextInt();
int V=sc.nextInt();
int D[]=new int[N+1];
int W[]=new int[N+1];
for(int i=1;i<=N;i++){
D[i]=sc.nextInt();
W[i]=sc.nextInt();
W[i]+=W[i-1];
}
//定义dp[i][j][2],看成二维dp表,一个单元格存两个数,就好理解。
//将数组分为三部分,最中间的是处理过的,那么肯定右两个指针分割它们,那么,dp[i][j]的意义为
//已经处理过的部分[i,j],消耗的最小能源值是多少
//每次去往下一个地方,就是i和j向左右扩展,并且工作人员当前要嘛在i处,要吗在j处
//每次去往下一个地方花的时间算出来,乘以[1,i-1]以及[i+1,N]上的功率总和。就是浪费的时间
//W[i]就是用来加速求一个段上的总和的,比如总和[1,i]就是W[i],总和[i+1,N],就是W[N]-W[i]
//dp[][][0]的意思是,当前位置在左边的状态,同理dp[][][1]表示当前位置在右边的状态
//显然,最开始的时候当前位置即可以看作在左边,也可以看作在右边,那么的dp[V][V][0]=dp[V][V][1]=0
//最终结束的位置是dp[1][N]
long dp[][][]=new long[N+1][N+1][2];
//画表后得知,三个条件,i<=V,j>=V,且i<j,可知只需对右上角的小正方形做dp即可(其左底角位置为[V][V])
//状态依赖为dp[i][j]依赖dp[i+1][j]和dp[i][j-1]。具体看dp主体。可知每个单元格依赖它下面的和左边的,即从下到上,从左往右dp即可。
//那么,需要填写base case,即第V行的前V个,和第V列的前V个
//第V列 从下往上时,dp只依赖于它下面的,根据意义可知,它下面的单元格j是固定为V的,回归到题意,说明一次也不能往右移动,每次都只能往左移动
//所以dp[i][V][0]是如何求的,很容易理解
//而dp[i][V][1]怎么求呢,很简单,dp[i][V][0]变为dp[i][V][1],意思就是从这头跑到那头,不关任何灯
for(int i=V-1;i>0;i--){
dp[i][V][0]=dp[i+1][V][0]+(D[i+1]-D[i])*(W[i]+W[N]-W[V]);
dp[i][V][1]=dp[i][V][0]+(D[V]-D[i])*(W[i-1]+W[N]-W[V]);
}
//同理求dp[V][i]..
for(int i=V+1;i<=N;i++){
dp[V][i][1]=dp[V][i-1][1]+(D[i]-D[i-1])*(W[V-1]+W[N]-W[i-1]);
dp[V][i][0]=dp[V][i][1]+(D[i]-D[V])*(W[V-1]+W[N]-W[i]);
}
//写不写都行,dp[V][V][0]=dp[V][V][1]=0;
for(int i=V-1;i>0;i--){
for(int j=V+1;j<=N;j++){
dp[i][j][0]=Math.min(dp[i+1][j][1]+(D[j]-D[i])*(W[i]+W[N]-W[j]),dp[i+1][j][0]+(D[i+1]-D[i])*(W[i]+W[N]-W[j]));
dp[i][j][1]=Math.min(dp[i][j-1][0]+(D[j]-D[i])*(W[i-1]+W[N]-W[j-1]),dp[i][j-1][1]+(D[j]-D[j-1])*(W[i-1]+W[N]-W[j-1]));
}
}
System.out.println(Math.min(dp[1][N][0],dp[1][N][1]));
}
}
}