題目鏈結
\(\mathcal{}\)
**這題是我在某奧賽一本通(提高篇)——樹形dp中的第一道例題,抱著試一試的心態,本蒟蒻嘗試了這道題。在過了n小時後,終於做出了這題
以上純屬扯淡
**首先,我們仔細看一下題目,可以發現——這是一棵樹呀!所以,我們就需要用到樹上dp。
那麼,我們應該怎麼設定狀態呢?
**上面這張醜陋的圖,紅色的數字表示這條樹枝所有的蘋果數量。
我們有沒有了一些靈感,如果沒有,那麼我在來給一些提示
1.保留這根樹枝,獲得它的蘋果數
2.不保留這根樹枝
so,我們的狀態有一維是樹枝的數量
但是,這個轉移方程是有問題的,\(why???\)
好了現在的就應該對了,我們把細節留在程式裡面
\(\mathcal\)
#include #include using namespace std;
struct node
;node e[2*101];
int dp[101][101];
int head[101],n,q,tot=0;
void add(int x,int y,int z) //鄰接表存數
,cnt=0; //son[1]表示f的左兒子在第幾條邊,son[2]表示f的右兒子在第幾條邊
bool flag=false;
for(int xun=head[f];xun;xun=e[xun].next)
}if(!flag) //如果沒有兒子,說明它是葉子結點,直接回溯
for(int i=1;i<=q;i++) //dp部分
}}int main()
dfs(1,0,0);
printf("%d",dp[1][q]); //因為最終我們要求的蘋果數是以1為根節點的子樹中保留q根樹枝的最大蘋果數,所以最終的結果等於dp[1][q]
return 0;
}
P2015 二叉蘋果樹
這道題的dp還是先更新子節點,在更新父節點,不過問題就是怎樣更新他們 我們定義ff i j 為第i個節點字數上共保留j條邊的情況下最多的蘋果數,對於每乙個點,他保留的邊必然是他直接保留的之前保留的邊和他當前兒子保留的邊的值的和加上這一條邊的 邊權,即ff u i max ff u i f u i j...
P2015 二叉蘋果樹
題面 設f u i 表示u的子樹上保留i條邊,至多保留的蘋果數目 那麼狀態轉移方程也就顯而易見了 f u i max f u i f u i j 1 f v j e i w 1 i min q,sz u 0 j min sz v i 1 u表示當前節點,v是u的乙個子節點,sz u 表示u的子樹上的...
P2015 二叉蘋果樹
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋...