首页 > 代码库 > codevs1258 关路灯(☆区间dp)
codevs1258 关路灯(☆区间dp)
1258 关路灯
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 大师 Master
题目描述 Description
多瑞卡得到了一份有趣而高薪的工作。每天早晨他必须关掉他所在村庄的街灯。所有的街灯都被设置在一条直路的同一侧。
多瑞卡每晚到早晨5点钟都在晚会上,然后他开始关灯。开始时,他站在某一盏路灯的旁边。
每盏灯都有一个给定功率的电灯泡,因为多端卡有着自觉的节能意识,他希望在耗能总数最少的情况下将所有的灯关掉。
多端卡因为太累了,所以只能以1m/s的速度行走。关灯不需要花费额外的时间,因为当他通过时就能将灯关掉。
编写程序,计算在给定路灯设置,灯泡功率以及多端卡的起始位置的情况下关掉所有的灯需耗费的最小能量。
输入描述 Input Description
输入文件的第一行包含一个整数N,2≤N≤1000,表示该村庄路灯的数量。
第二行包含一个整数V,1≤V≤N,表示多瑞卡开始关灯的路灯号码。
接下来的N行中,每行包含两个用空格隔开的整数D和W,用来描述每盏灯的参数,其中0≤D≤1000,0≤W≤1000。D表示该路灯与村庄开始处的距离(用米为单位来表示),W表示灯泡的功率,即在每秒种该灯泡所消耗的能量数。路灯是按顺序给定的。
输出描述 Output Description
输出文件的第一行即唯一的一行应包含一个整数,即消耗能量之和的最小值。注意结果小超过1,000,000,000。
样例输入 Sample Input
4
3
2 2
5 8
6 1
8 7
样例输出 Sample Output
56
#include<iostream> #include<cstdio>#include<cstring>using namespace std;int d[100],w[100],s,n;int f[100][100][3];//如果关闭一个区间的灯,最后人一定在这个区间的左边或右边,关了左边或右边的灯去中间没必要。//f[i][j][0]表示关了[i,j]区间的灯最后人在i点的最优值,f[i][j][1]表示关了[i,j]区间的灯最后人在j点的最优值int main(){ scanf("%d%d",&n,&s); for(int i=1;i<=n;i++) scanf("%d%d",&d[i],&w[i]),w[i]+=w[i-1]; memset(f,127/3,sizeof(f)); f[s][s][0]=f[s][s][1]=0; for(int i=s;i>=1;i--) for(int j=i+1;j<=n;j++) { f[i][j][0]=min(f[i+1][j][0]+(d[i+1]-d[i])*(w[n]-(w[j]-w[i])),f[i][j][0]); f[i][j][0]=min(f[i+1][j][1]+(d[j]-d[i])*(w[n]-(w[j]-w[i])),f[i][j][0]); f[i][j][1]=min(f[i][j-1][1]+(d[j]-d[j-1])*(w[n]-(w[j-1]-w[i-1])),f[i][j][1]); f[i][j][1]=min(f[i][j-1][0]+(d[j]-d[i])*(w[n]-(w[j-1]-w[i-1])),f[i][j][1]); } printf("%d",min(f[1][n][1],f[1][n][0]));}
codevs1258 关路灯(☆区间dp)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。