TOJ1174(戰略遊戲 版本二 )

2021-05-27 02:47:27 字數 1679 閱讀 8543

演算法:樹型dp

與戰略遊戲1不同的是,戰略遊戲1是看邊,也就是只能由父親結點看子結點,而本題是某個結點可以由父親看,可以放士兵,也可以讓兒子看,因此有三種狀態。有三種轉移方式。

f[t,0]表示t被父親結點的士兵守衛。因此f[t,0]=f[t,0]+σmin(f[tot[t,i],1],f[tot[t,i],2])。tot[t,i]表示t的第i個兒子。dp方程可以解釋為:若當前結點被父親結點守衛,則它的子節點要麼放守衛,要麼被子結點守衛,兩者取乙個最小值。

f[t,1]表示t放士兵守衛。因此f[t,1]=f[t,1]+1+σmin(f[tot[t,i],1],f[tot[t,i],2],f[tot[t,i],3])。若這個點放士兵,子結點可以被父親守衛,可以放士兵,也可以被子子結點守衛。

f[t,2]表示t被子結點守衛。因此f[t,2]=f[t,2]+min(f[tot[t,i],1])+σmin(f[tot[t,i],1],f[tot[t,i],2])。若這個點被子結點守衛,子結點必須有乙個點放士兵,通過打擂台找到這個士兵。同時其它點可以放士兵,也可以被子結點守衛,在計算時就不能再把放士兵的那個點算上。

program toj1147;

const

maxn1=1500;

var f:array [0..maxn1,0..2] of longint;

tot:array [0..maxn1,0..maxn1] of longint;

fa:array [0..maxn1] of longint;

n,root:longint;

procedure init;

var i,j,x,t,y:longint;

begin

fillchar(f,sizeof(f),0);

fillchar(fa,sizeof(fa),255);

readln(n);

for i:=1 to n do

begin

read(x,t);

tot[x,0]:=t;

for j:=1 to t do

begin

read(y);

tot[x,j]:=y;

fa[y]:=x;

end;

readln;

end;

for i:=0 to n-1 do

begin

if fa[i]=-1 then

begin

root:=i;

break;

end;

end;

end;

function min(x,y:longint):longint;

begin

if xp then inc(sum,min(f[tot[t,i],1],f[tot[t,i],2]));

f[t,2]:=sum;

end;

begin

assign(input,'toj1174.in'); reset(input);

assign(output,'toj1174.out'); rewrite(output);

init;

tree_dp(root);

writeln(min(f[root,1],f[root,2]));

close(input); close(output);

end.

TYVJ3097 3121 3369 戰略遊戲

給一棵n個節點的樹,在點上放置士兵,每個士兵能監視周圍的所有邊,詢問最少放置的士兵數dp i,0 表示在 i點不放 士兵合法 的最小放 置數dp i,1 表示在 i點放士 兵合法的 最小放置 數 dp i,0 d p so n i 1 dp i 1 dp son i 1 d p so n i 0 m...

P2016 戰略遊戲

樹形dp f u 0 表示 uf u 0 表示u f u 0 表示u 號節點不放士兵,以x為根的子樹需要的最少士兵數。f u 1 表示 uf u 1 表示u f u 1 表示u 號節點放士兵,以x為根的子樹需要的最少士兵數。由於我們定義的是將其完全覆蓋,則我們不需要考慮父親節點,為什麼?當我們已經回...

藍書 323 戰略遊戲

f i 2 以i為根的子樹,i節點不放置士兵滿足條件的最小放置士兵數量。樹形dp一下就行 比較奇怪的是 讀入scanf d d u,m 是對的 scanf d s u,s int m s 2 0 這樣就會超時。有懂得大佬解答下嗎。include using namespace std typedef...