背景 Background
Bless all rp++..
描述 Description
在一个数轴上,有n个MM(绝非恐龙!)在哭泣(5555~一直哭).
tcboy也在这个数轴上,并恰好看到了这一幕,由于每个MM哭都会让tcboy损失一定的rp,于是tcboy有必要去安慰她们.(真命苦啊 T.T)
开始时,tcboy站在k号MM的旁边.
现在知道第i个MM哭泣每秒钟会使tcboy降低 w[i]的rp (单位rp/s).
而tcboy的行走速度很慢只有1m/s .
tcboy安慰MM的方式很特别(怎么安慰随便大家YY了..#@$%^%$#@),不需要花费时间.
请计算tcboy安慰完所有MM,会消耗掉的rp的最小值.
tcboy也在这个数轴上,并恰好看到了这一幕,由于每个MM哭都会让tcboy损失一定的rp,于是tcboy有必要去安慰她们.(真命苦啊 T.T)
开始时,tcboy站在k号MM的旁边.
现在知道第i个MM哭泣每秒钟会使tcboy降低 w[i]的rp (单位rp/s).
而tcboy的行走速度很慢只有1m/s .
tcboy安慰MM的方式很特别(怎么安慰随便大家YY了..#@$%^%$#@),不需要花费时间.
请计算tcboy安慰完所有MM,会消耗掉的rp的最小值.
输入格式 InputFormat
输入文件的第一行包含一个整数N,2<=N<=1000,表示MM的数量。
第二行包含一个整数V,1<=V<=N,表示开始时tcboy站在几号MM的旁边.
接下来的N行中,每行包含两个用空格隔开的整数D和W,用来描述每个MM,其中0<=D<=1000,0<=W<=1000。D表示MM在数轴上的位置(单位: m),W表示每秒钟会使tcboy降低W的rp。
第二行包含一个整数V,1<=V<=N,表示开始时tcboy站在几号MM的旁边.
接下来的N行中,每行包含两个用空格隔开的整数D和W,用来描述每个MM,其中0<=D<=1000,0<=W<=1000。D表示MM在数轴上的位置(单位: m),W表示每秒钟会使tcboy降低W的rp。
输出格式 OutputFormat
输出只有一行:一个整数,即消耗rp之和的最小值。结果不超过1,000,000,000。
样例输入 SampleInput
[复制数据]
样例输出 SampleOutput
[复制数据]
数据范围和注释 Hint
注意结果的大小。
时间限制 TimeLimitation
当然是1s ~~
从最后一步开始想。最后一步只能是安慰第1个或安慰最后一个妹子。
而且每个时刻,安慰过的妹子们必然是连续的。
因此可以想到每次扩展这个区间来转移状态
设f[i,j,1]表示 已经安慰完[i,j]这个区间的妹子 且最后安慰的是第i个妹子
f[i,j,2]则表示最后安慰的是第j个妹子
f[i,j,1]=max( f[i+1,j,1]+(d[i+1]-d[i])*(s[i]+s[n]-s[j] ),
f[i+1,j,2]+(d[j]-d[i])*(s[i]+s[n]-s[j] );
f[i,j,2]=max( f[i,j-1,1]+(d[j]-d[i])*(s[i-1]+s[n]-s[j-1] ),
f[i,j-1,2]+(d[j]-d[j-1])*(s[i-1]+s[n]-s[j-1] );
最后答案为max( f[1,n,1] , f[1,n,2] )
但是种转移方程不容易确定它的顺序。。。
于是我写了一个记忆化搜索。
var i,j,n,k,kk:longint;
d,w:array[0..1001]of longint;
f:array[0..1001,0..1001,1..2]of int64;
s:array[0..1000]of longint;
function min(a,b:int64):int64;
begin
if a>b then exit(b) else exit(a);
end;
function dp(i,j,k:longint):int64;
var a1,a2:longint;
begin
if f[i,j,k]<>-1 then exit(f[i,j,k]);
if k=1 then
begin
a1:=dp(i+1,j,1)+(d[i+1]-d[i])*(s[i]+s[n]-s[j]);
a2:=dp(i+1,j,2)+(d[j]-d[i])*(s[i]+s[n]-s[j]);
f[i,j,k]:=min(a1,a2);
exit(f[i,j,k]);
end;
if k=2 then
begin
a1:=dp(i,j-1,1)+(d[j]-d[i])*(s[i-1]+s[n]-s[j-1]);
a2:=dp(i,j-1,2)+(d[j]-d[j-1])*(s[i-1]+s[n]-s[j-1]);
f[i,j,k]:=min(a1,a2);
exit(f[i,j,k]);
end;
end;
begin
//assign(input,'input.in');assign(output,'output.out');reset(input);rewrite(output);
readln(n);
readln(kk);
for i:=0 to 1001 do for j:=0 to 1001 do for k:=1 to 2 do f[i,j,k]:=1000000001;
fillchar(s,sizeof(s),0);
for i:=1 to n do readln(d[i],w[i]);
for i:=1 to n-1 do for j:=i+1 to n do
for k:=1 to 2 do f[i,j,k]:=-1;
for i:=1 to n do s[i]:=s[i-1]+w[i];
f[kk,kk,1]:=0;f[kk,kk,2]:=0;
writeln(min(dp(1,n,1),dp(1,n,2)));
//close(input);close(output);
end.