題目鏈結
設f[i][j][k]表示給以i為根節點的子樹分配j條可保留的樹枝名額的時候,狀態為k時能保留的最多蘋果。
k有三種情況。
k=1:我只考慮子樹的左叉,不考慮子樹的右叉,此時子樹能保留的最多的蘋果。
k=2:我只考慮子樹的右叉,不考慮子樹的左叉,此時子樹能保留的最多的蘋果。
k=3:我既考慮子樹的左叉,又考慮子樹的右叉,此時子樹能保留的最多的蘋果。
這樣狀態轉移方程就出來了。
f[i][j][1]=max(f[i][j][1],f[leftson[i]][j-1][3]+val[i][leftson[i]])
f[i][j][2]=max(f[i][j][2],f[rightson[i]][j-1][3]+val[i][rightson[i]])
f[i][j][3]=max(f[i][j][3],f[i][v][1]+f[i][j-v][2]) 其中v從0到j列舉。
最後f[1][q][3]就是最終的答案。
注意記憶化搜尋。我因為這個t了四次。
#include#include#include
using
namespace
std;
inline
long
long
read()
while
(isdigit(ch))
return num*f;
}struct
edgeedge[
100010
];int head[100010
],num;
int father[100010
];int size[100010
];inline
void add(int
from,int to,int
val);
head[
from]=num;
}void find(int x,int
fa) }
}int f[103][103][4
];void dfs(int x,int
s) }
for(int v=0;v<=s;++v)
f[x][s][
3]=max(f[x][s][3],f[x][v][1]+f[x][s-v][2
]);
return;}
intmain()
find(
1,1);
dfs(
1,q);
printf("%d
",f[1][q][3
]);
return0;
}
Luogu P2015 二叉蘋果樹
題目描述 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果。給定...
luogu P2015 二叉蘋果樹
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果...
Luogu P2015 二叉蘋果樹
題目鏈結 樹上零一dp 記憶化搜尋 如果是空結點 如果是葉子結點直接返回蘋果數 以上都不滿足的話,dp狀態轉移 設定dp的轉移,轉移到左右兒子結點 for int i 1 i結果31分 1.說白了,記憶化搜尋還不是掌握的特別好 2.其次狀態設計不是特別好,在儲存左右兒子時,應該該需要儲存邊的 inc...