簡單版的動態規劃
阿新 • • 發佈:2019-02-07
問題描述
小北很喜歡玩計算機遊戲,特別是戰略遊戲,但是有時他不能儘快找到解所以常常感到很沮喪。現在面臨如下問題:他必須在一箇中世紀的城堡裡設防,城堡裡的道路形成一棵無向樹。要在結點上安排最少的士兵使得他們可以看到所有邊。你能幫助他嗎?
你的任務是給出士兵的最少數目。
輸入格式
輸入包含多組資料。每組資料表示一棵樹,在每組資料中:
第一行是結點的數目。
接下來的幾行,每行按如下格式描述一個結點:
結點識別符號 : ( 道路的數目 ) 結點識別符號1 結點識別符號2 ...... 結點識別符號道路的數目
或者
結點識別符號 : (0)
對於 n (0<n<=1500) 個結點,結點識別符號是一個從 0 到 n - 1 的整數。每條邊在測試用例中只出現一次。
輸出格式
對於每組資料,各給出一個整數表示士兵的最少數目.
測試輸入4 0:(1) 1 1:(2) 2 3 2:(0) 3:(0) 5 3:(3) 1 4 2 1:(1) 0 2:(0) 0:(0) 4:(0)測試輸出
1 2原始碼
#include <stdio.h> #include <string.h> #define min(x,y) ((x>y)?y:x) #define N 1504 int dp[N][2], father[N], v[N], n; int main() { int i, j, k, t1, t2, root=0; void DFS(int root); while(scanf("%d",&n)!=EOF){ memset(dp,0,sizeof(dp)); memset(father,0,sizeof(father)); memset(v,0,sizeof(v)); for(i=0;i<n;i++){ scanf("%d:(%d)",&t1,&t2); if(i==0) root=t1; for(j=0;j<t2;j++){ scanf("%d",&k); father[k]=t1; } } DFS(root); printf("%d\n",min(dp[root][0],dp[root][1])); } return 0; } void DFS(int root) { v[root]=1; for(int i=0;i<n;i++){ if(!v[i] && father[i]==root){ DFS(i); dp[root][1]=dp[root][1]+dp[i][0]; dp[root][0]=dp[root][0]+min(dp[i][0],dp[i][1]); } } dp[root][0]++; }