POJ1947 樹狀DP 揹包問題

2021-06-22 16:49:17 字數 1482 閱讀 1403

/*

* cpp0.cpp

* * created on: 2023年7月8日

* author: miao

*/#include #include #include #include using namespace std;

vectorv[155];

int dp[155][155];

int n,p;

const int inf=0xffffff;

void dfs(int root)

{ int i,j,k;

//先計算完畢所有子樹

for (i=0;i<(int)v[root].size();i++)

dfs(v[root][i]);

dp[root][1]=0;

//類似揹包問題的dp,對於第i個子樹,拿或者不拿兩種情況

for (i=0;i<(int)v[root].size();i++)

{ int son=v[root][i];

//維護dp[root][1..p]

for (j=p;j>=1;j--)

{ int temp=dp[root][j]+1;//如果不拿第i個子樹,則切斷這個子樹,次數+1

//如果拿第i個子樹,需列舉第i個子樹中要取多少個點,假設第i個子樹取k個,從上乙個狀態(第1..i-1個子樹)取j-k個,找出最小值

for (k=1;k順推要增加一維:

/** cpp0.cpp

* * created on: 2023年7月8日

* author: miao

*/#include #include #include #include using namespace std;

vectorv[155];

int dp[155][155][155];

int n,p;

const int inf=0xffffff;

void dfs(int root)

{ int i,j,k;

//先計算完畢所有子樹

for (i=0;i<(int)v[root].size();i++)

dfs(v[root][i]);

dp[0][root][1]=0;

//類似揹包問題的dp,對於第i個子樹,拿或者不拿兩種情況

for (i=1;i<=(int)v[root].size();i++)

{ int son=v[root][i-1];

int son_size=v[son].size();

//維護dp[root][1..p]

for (j=1;j<=p;j++)

{ int temp=dp[i-1][root][j]+1;//如果不拿第i個子樹,則切斷這個子樹,次數+1

//如果拿第i個子樹,需列舉第i個子樹中要取多少個點,假設第i個子樹取k個,從上乙個狀態(第1..i-1個子樹)取j-k個,找出最小值

for (k=1;k

poj 1947 樹dp 揹包問題

看了很多題解都是直接一遍dfs就搞定的方法,但是我實在是沒看懂那個轉移方程。最後在茫茫部落格中終於發現了乙個有邏輯的方法,但是複雜度好像要高一些,但是還是把這個題過了。include include include using namespace std const int maxn 155 vec...

題解 poj1947 樹形DP

題目鏈結 dp root j 以root為根節點的子樹,得到 j 個節點的子樹需要最少減掉的邊數,注意子樹中必須保留root節點。否則無法dp 那麼很明顯的邊界條件dp root 1 num 兒子的個數 因為要只剩乙個節點的子樹,那麼所有的孩子都減掉,這樣就為兒子的個數。那麼狀態轉移方程呢 dp r...

POJ 1947 樹形DP入門題

給出n個點,n 1個關係,建出樹形圖,問最少減去幾個邊能得到節點數為p的樹。典型樹形dp題 dp cur j 記錄cur結點,要得到一棵j個節點的子樹去掉的最少邊數 轉移方程用的揹包的思想 對當前樹的每乙個子樹進行計算 砍掉此子樹 dp cur j dp cur j 1 不砍掉 for l 0 l ...