將功補過 樹形DP

2021-07-11 18:41:36 字數 3106 閱讀 9755

題意/description

作為間諜專家的elvis han受竊取x星球軍事中心的秘密情報,他已經成功進入軍事中心。但是很不幸的是,在他還沒有找到任務需要情報的時候就被發現,這時他清楚他不可能完成任務了,不過還有機會將功補過,也就是得到一些不如任務情報有價值的其他情報,如果得到的情報的總價值大於等於任務情**值,他也不會受到懲罰。很幸運的是他已經得到的軍事中心的地圖,情報都是隱藏在各個道路上的,但是他只有時間遍歷一定數量的路(時間寶貴呀!還要逃跑。。)現在你做為他的助手,給你地圖和每個道路情**值,希望你分析出,看他能不能將功補過。 

軍事中心是乙個嚴格的二叉樹,也就是說,如果有個點可以分道,一定是分出,也只分出2條道路,現在elvis han正處在第乙個分道處,也就是說樹的根結點處。每條道路上都有乙個分數,就是這個道路上的情**值。但是他只有時間走m條路,他的最終情**值總和就是他所經過的路的情**值總和(假設他到過的路一定可以把所有情報得到)希望你給出乙個方案使得他可以盡量多地獲取情報以便將功補過。 

讀入

/input:

共有n行: 

第一行:3個資料:n,m,q(n表示有多少個路口,包括分道和不分道的路口;m表示他可以有時間走的道路總數;q表示他的任務情報的價值) 

第2~n行:每行3個資料,xi,yi,wi (x,y表示第i條道路連線的2個路口,w表示這條道路上的情**值分, 注意,所有資料均在lonint範圍內) 

輸出

/output:

共包含2行: 

第一行:輸出true/false(注意大小寫),表示他是否可以收集夠任務情**值 

第二行:輸出乙個資料: 

如果他可以完成任務,就輸出他收集的情報總價值超過任務情**值的部分。(非負數) 

如果不能完成任務,就輸出乙個數,表示他不能還差多少分才夠任務情**值。(負數) 

題解/

solution

這道題故事講得不錯,似乎很煩。可如果是理解了樹型dp,就會發現這是二叉蘋果樹,程式結尾判斷一下就ok了。是不是被嚇傻了吧。

**

/code:

var

f,g,a:array [0..101,0..101] of longint;

v:array [0..101] of boolean;

l,r:array [0..101] of longint;

n,m,q,t:longint;

function max(o,p:longint):longint;

begin

if o>p then exit(o);

exit(p);

end;

procedure tree(x:longint);

var i:longint;

begin

if x=0 then exit;

v[x]:=true;

for i:=1 to a[x,0] do

if not v[a[x,i]] then

begin

if l[x]=0 then l[x]:=a[x,i]

else r[x]:=a[x,i];

end;

tree(l[x]);

tree(r[x]);

end;

procedure main(t,x:longint);

var i:longint;

begin

if (x=0) or (t=0) then

begin

f[t,x]:=0;

exit;

end;

if f[t,x]>0 then exit;

if x=1 then

begin

f[t,x]:=max(g[t,l[t]],g[t,r[t]]);

exit;

end;

for i:=0 to x-2 do

begin

main(l[t],i);

main(r[t],x-2-i);

f[t,x]:=max(f[t,x],f[l[t],i]+f[r[t],x-2-i]);

end;

f[t,x]:=f[t,x]+g[t,l[t]]+g[t,r[t]];

main(l[t],x-1);

f[t,x]:=max(f[t,x],f[l[t],x-1]+g[t,l[t]]);

main(r[t],x-1);

f[t,x]:=max(f[t,x],f[r[t],x-1]+g[t,r[t]]);

end;

procedure init;

var i,x,y,w:longint;

begin

readln(n,m,q);

for i:=1 to n-1 do

begin

readln(x,y,w);

g[x,y]:=w; g[y,x]:=w;

inc(a[x,0]); a[x,a[x,0]]:=y;

inc(a[y,0]); a[y,a[y,0]]:=x;

end;

for i:=1 to n do

if a[i,0]=2 then

begin

t:=i;

break;

end;

end;

procedure print;

begin

if f[t,m]>=q then

begin

writeln('true');

write(f[t,m]-q);

exit;

end;

writeln('false');

write(f[t,m]-q);

end;

begin

init;

tree(t);

main(t,m);

print;

end.

將功補過(樹形dp)

description 作為間諜專家的elvis han受竊取x星球軍事中心的秘密情報,他已經成功進入軍事中心。但是很不幸的是,在他還沒有找到任務需要情報的時候就被發現,這時他清楚他不可能完成任務了,不過還有機會將功補過,也就是得到一些不如任務情報有價值的其他情報,如果得到的情報的總價值大於等於任務...

將功補過 樹形DP

time limit 10000ms memory limit 65536k total submit 41 accepted 28 case time limit 1000ms description 作為間諜專家的elv is elvis elvishan hanha n受竊取x xx星球軍事中...

2005 2 3 加班啦,算是將功補過

又遲到了,5555555555555555555555555 把分診的問題改好了 裝置維護中增加了乙個屬性 分診主機 這個屬性的作用確定用哪台工作站為該裝置分診,當為空時表示不參加分診 分診模組中根據上述屬性確定要控制分診的裝置 只對 分診主機 屬性是該工作站名稱的裝置分診 同時分診中僅顯示與參與分...