題目鏈結
點加權的最小覆蓋
題目說的很清楚,用最少的點覆蓋所有的點。題目給出的是個樹,所以可以用動態規劃來解決。
給出如下定義:
f[i,0]表示i點不放,i可以被父親節點觀察到;
f[i,1]表示i點不放,i可以被兒子節點觀察到;
f[i,2]表示i點放,在i處設定警衛;
轉移如下:
1、由f[i,0]定義可知,設j為i的兒子節點,兒子節點都需要被觀察到,但由於根節點i不放,所以兒子必須保證能被觀察到,即f[j][1],f[j][2],所以我們需要列舉必須放置的兒子節點,即下:
f[i,0] = ∑(min(f[j][1],f[j,2]))}
其中i為列舉兒子節點
2、由f[i,1]定義可知,i的兒子結點中一定有乙個結點有直接警衛,其它兒子節點必須都要被觀察到,即下:
f[i,1] =min(∑(min(f[j,1],f[j,2])+f[k,2])
其中k為列舉的必放的兒子節點,j為除了k之外的兒子節點
3、由f[i,2]定義可知,i點放置了守衛,所以對於每個兒子節點都能被觀察到,取f[j,0],f[j,1],f[j,2]最小值即可,即下:
f[i,2] = min(f[j,0],f[j,1],f[j,2])
j是i的兒子節點
/*1.確定建立模型題目說的很清楚,用最少的點覆蓋所有的點。題目給出的是個樹,所以可以用動態規劃來解決。
給出如下定義:
f[i,0]表示i點不放,i可以被父親節點觀察到;
f[i,1]表示i點不放,i可以被兒子節點觀察到;
f[i,2]表示i點放,在i處設定警衛;
轉移如下:
1、由f[i,0]定義可知,設j為i的兒子節點,兒子節點都需要被觀察到,但由於根節點i不放,所以兒子必須保證能被觀察到,即f[j][1],f[j][2],所以我們需要列舉必須放置的兒子節點,即下:
f[i,0] = ∑(min(f[j][1],f[j,2]))}
其中i為列舉兒子節點
2、由f[i,1]定義可知,i的兒子結點中一定有乙個結點有直接警衛,其它兒子節點必須都要被觀察到,即下:
f[i,1] =min(∑(min(f[j,1],f[j,2])+f[k,2])
其中k為列舉的必放的兒子節點,j為除了k之外的兒子節點
3、由f[i,2]定義可知,i點放置了守衛,所以對於每個兒子節點都能被觀察到,取f[j,0],f[j,1],f[j,2]最小值即可,即下:
f[i,2] = min(f[j,0],f[j,1],f[j,2])
j是i的兒子節點
*/#include
#include
#include
#define fora(i,s,e) for(int i=s;i<=e;i++)
#define fors(i,s,e) for(int i=s;i>=e;i--)
using
namespace
std;
const
int n=1500,m=1500,inf=2147483647
;int n,m,root,num_edge,head[n+1],a[n+1],f[n+1][3
];/*
f[u][0]表示的是結點u可以被父親看到的安排的u為樹根的子樹安排的最少的警衛數
f[u][1]表示的是結點u可以被兒子看到的安排的u為樹根的子樹安排的最少的警衛數
f[u][2]表示的是結點u上安排警衛時的u為樹根的子樹安排的最少的警衛數
*/struct
edgeedge[
2*m+2
]; void add_edge(int
from,int to) ,head[from]=num_edge;}
inline
int min(int fa,int fb)
void dp(int u,int
fa) }
f[u][
1]+=d,f[u][2]+=a[u];
/*狀態轉移方程
當點u可以被父親看到的安排的u為樹根的子樹安排的最少的警衛數為保證子結點能夠全部觀察到,則為min(f[v][1],f[v][2])的和
當點u可以被兒子看到的安排的u為樹根的子樹安排的最少的警衛數為保證子結點能夠全部觀察到,則至少有乙個兒子結點必須要選,f[i,0] = min
當點u上安排警衛時的u為樹根的子樹安排的最少的警衛數為兒子結點的三者的min,f[i,2] = min(f[j,0],f[j,1],f[j,2])
*/}intmain()
root=1,dp(root,0
); printf("%d
",min(f[root][1],f[root][2
]));
return0;
}/*61 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0
*/
2.構建知識架構,模型體系
題目說的很清楚,用最少的點覆蓋所有的點。題目給出的是個樹,所以可以用動態規劃來解決。
給出如下定義:
f[i,0]表示i點不放,且以i為根節點的子樹(包括i節點)全部被觀察到;
f[i,1]表示i點不放,且以i為根節點的子樹(可以不包括i節點)全部被觀察到;
f[i,2]表示i點放,且以i為根節點的子樹全部被觀察到;
轉移如下:
1、由f[i,0]定義可知,設j為i的兒子節點,至少要有乙個i的兒子節點是放置守衛的,其餘的兒子節點可放可不放,但由於根節點i不放,所以其餘的兒子節點如果不放的話,必須保證能被觀察到,即f[j][0];所以我們需要列舉必須放置的兒子節點,即下:
f[i,0] = min
其中k為列舉的必放的兒子節點,j為除了k之外的兒子節點
2、由f[i,1]定義可知,i可以被觀察到也可以不被觀察到,但兒子節點必須都要被觀察到,即下:
f[i,1] =∑(min(f[j,0],f[j,2]))
j是i的兒子節點
3、由f[i,2]定義可知,i點放置了守衛,所以對於每個兒子節點都能被觀察到,取f[j,0],f[j,1],f[j,2]最小值即可,即下:
f[i,2] = min(f[j,0],f[j,1],f[j,2]) j是i的兒子節點
對於葉節點i,f[i,0] = f[i,2] = data[i],f[i,1] = 0;
講得已經十分詳細了,剩下自己解決吧。
皇宮看守(guard)
問題描述 太平王世子事件後,陸小鳳成了皇上特聘的御前一品侍衛。皇宮以午門為起點,直到後宮嬪妃們的寢宮,呈一棵樹的形狀 有邊直接相連的宮殿可以互相望見。大內保衛森嚴,三步一崗,五步一哨,每個宮殿都要有人全天候看守,在不同的宮殿安排看守所需的費用不同。可是陸小鳳手上的經費不足,無論如何也沒法在每個宮殿都...
皇宮看守 樹形DP
題意 description 太平王世子事件後,陸小鳳成了皇上特聘的御前一品侍衛。皇宮以午門為起點,直到後宮嬪妃們的寢宮,呈一棵樹的形狀 某些宮殿間可以互相望見。大內保衛森嚴,三步一崗,五步一哨,每個宮殿都要有人全天候看守,在不同的宮殿安排看守所需的費用不同。可是陸小鳳手上的經費不足,無論如何也沒法...
皇宮看守(樹形dp)
description 太平王世子事件後,陸小鳳成了皇上特聘的御前一品侍衛。皇宮以午門為起點,直到後宮嬪妃們的寢宮,呈一棵樹的形狀 某些宮殿間可以互相望見。大內保衛森嚴,三步一崗,五步一哨,每個宮殿都要有人全天候看守,在不同的宮殿安排看守所需的費用不同。可是陸小鳳手上的經費不足,無論如何也沒法在每個...