//树形DP
uses math;
type tre=record
left,right,fa:longint;
end;
var t:array[0..100000]of tre;
tree:array[1..100000,0..2]of longint;
h,c,stack:array[1..100000]of longint;
d:array[0..100000,0..5]of int64;
root,n,k:longint;
procedure writel;
var i,j:longint;
ans:int64;
begin
ans:=high(int64);
for i:=0 to k do
ans:=min(ans,d[root,i]);
writeln(ans);
end;
procedure DP(x:longint);
var i,j,j1,j2,l:longint;
begin
if x=0 then exit;
DP(t[x].left);
DP(t[x].right);
for i:=0 to k do
for j:=0 to k-i do
begin
d[x,i+j]:=min(max(d[t[x].left,i],d[t[x].right,j])+c[x],d[x,i+j]);
if i+j+1<=k then
d[x,i+j+1]:=min(max(d[t[x].left,i],d[t[x].right,j]),d[x,i+j+1]);
end;
end;
procedure maketree;
var i,j,top,tot:longint;
begin
top:=0;
for i:=1 to n do
begin
{t[i].st:=h[i];
if top<>0 then
begin
tot:=top;
top:=i;
while (h[i]>t[tot].st)and(t[tot].fa<>0) do
tot:=t[tot].fa;
if h[i]>t[tot].st then
t[tot].fa:=i;
if (t[tot].fa<>0)and(tot<>top) then
begin
t[i].fa:=t[tot].fa;
t[tot].fa:=i;
end;
if (t[tot].fa<>0)and(tot=top) then
t[i].fa:=tot;
end
else
top:=1;}
j:=Top;
while (j>0)and(h[Stack[j]]<h[i]) do
dec(j);
if j<>Top then
t[Stack[j+1]].fa:=i;
if j<>0 then
t[i].fa:=Stack[j];
Top:=j+1;
Stack[Top]:=i;
end;
for i:=1 to n do
if t[i].fa=0 then
root:=i
else
begin
inc(tree[t[i].fa,0]);
tree[t[i].fa,tree[t[i].fa,0]]:=i;
end;
for i:=1 to n do
begin
t[i].left:=tree[i,1];
t[i].right:=tree[i,2];
end;
end;
procedure init;
var i,j:longint;
begin
readln(n,k);
for i:=1 to n do
readln(h[i],c[i]);
end;
begin
init;
maketree;
fillchar(d,sizeof(d),127);
d[0,0]:=0;
DP(root);
writel;
end.
GDSOI2008鱼肉炸弹
最新推荐文章于 2020-08-17 08:42:04 发布