1. 题目
Loongint的夜晚
【Description】
Loongint和MM在僻静的小镇上居住着,一天晚上,MM对Loongint说:“亲爱的,去把灯关掉。”Loongint十分兴奋,可发现MM亮了整整一排灯…Loongint必须关掉所有的灯…开始时他站在某一盏灯的旁边,每盏灯都有一个给定功率的电灯泡(!),因为Loongint有着自觉的节能意识(表扬),他希望在耗电能总数最少的情况下将所有的灯关掉。Loongint为了积攒精力,所以只能以1m/s的速度行走。关灯不需要花费额外的时间,因为当他通过时就能将灯关掉。
Loongint需要你在给定路灯设置和灯泡功率的情况下计算以及Loongint的起始位置的情况下关掉所有的灯需耗费的最小能量。
【Input】
输入文件的第一行包含一个整数N,2≤N≤1000,表示灯的数量。
第二行包含一个整数V,1≤V≤N,表示Loongint开始关灯的路灯号码。
接下来的N行中,每行包含两个用空格隔开的整数D和W,用来描述每盏灯的参数,其中0≤D≤1000,0≤W≤1000。D表示该灯与这排灯开始处的距离(用米为单位来表示),W表示灯泡的功率,即在每秒钟该灯泡所消耗的能量数。灯是按顺序给定的。
【Output】
输出文件的第一行即唯一的一行应包含一个整数,即消耗能量之和的最小值。注意结果不超过1,000,000,000。
【Sample Input】
4
3
2 2
5 8
6 1
8 7
【Sample Output】
56
2. 算法
这个就一水水的区间型动规,有点类似于沙子合并。
没啥好说的,直接上代码。
3. 注意事项
注意建模。
4. 代码
区间动规 (Loongint)
Program Night(input,output);
var F:array[0..1000,0..1000,0..1]of longint;
C,Sum:array[0..1000,0..1000]of longint;
D,W:array[0..1000]of longint;
n,v,i,j:longint;
Function min(a,b:Longint):longint;
begin
if a<b then exit(a) else exit(b);
end;
begin
assign(input,'Night.in');reset(input);
assign(output,'Night.out');rewrite(output);
readln(n);readln(v);
for i:=1 to n do readln(D[i],W[i]);
for i:=1 to n do
for j:=i to n do
Sum[i,j]:=Sum[i,j-1]+W[j];
for i:=1 to n do
for j:=i to n do
C[i,j]:=Sum[1,n]-Sum[i,j];
fillchar(F,sizeof(F),63);
F[0,0,0]:=0;F[0,0,1]:=0;
for i:=1 to v-1 do
begin
F[i,0,0]:=F[i-1,0,0]+C[v-i+1,v]*(D[v-i+1]-D[v-i]);
F[i,0,1]:=F[i,0,0]+C[v-i,v]*(D[v]-D[v-i]);
end;
for j:=1 to n-v do
begin
F[0,j,1]:=F[0,j-1,1]+C[v,v+j-1]*(D[v+j]-D[v+j-1]);
F[0,j,0]:=F[0,j,1]+C[v,v+j]*(D[v+j]-D[v]);
end;
for i:=1 to v-1 do
for j:=1 to n-v do
begin
F[i,j,0]:=min(f[i-1,j,0]+c[v-i+1,v+j]*(d[v-i+1]-d[v-i]),F[i-1,j,1]+c[v-i+1,v+j]*(d[v+j]-d[v-i]));
F[i,j,1]:=min(f[i,j-1,1]+c[v-i,v+j-1]*(d[v+j]-d[v+j-1]),f[i,j-1,0]+c[v-i,v+j-1]*(d[v+j]-d[v-i]));
end;
writeln(min(F[v-1,n-v,1],F[v-1,n-v,0]));
close(input);
close(output);
end.