題目鏈結
樹上依賴多重揹包,允許從根出發的一條鏈中每個點上的乙個物品免費,求最大價值。
揹包神仙題……
首先都能想到的就是列舉某個節點,這個節點到根上的所有節點使用一次免費的機會,那麼整棵樹就被分成了三部分:
1.這條鏈上所有點剩餘物品數量為ai−
1a_i-1
ai−1;
2.這條鏈左邊所有點不變。
3.這條鏈右邊所有點不變。
於是這裡可以按照dfs序來dp,f[i
][j]
f[i][j]
f[i][j
]表示dp到了第i個節點,選了j
jj個節點達到的最大價值。從子樹更新上來的時候由於要強制必選乙個點,因此每個點物品的上界應該是ai−
1a_i-1
ai−
1而不是a
ia_i
ai,這樣最後必選的那條鏈也剛好可以保證剩餘物品數量為ai−
1a_i-1
ai−1。
接下來翻轉所有節點掛的兒子順序,再做一遍上面的dp,只是要在dp完所有兒子之後再計算自己的貢獻。這個dp記為g[i
][j]
g[i][j]
g[i][j
],最後實際上就是求max
\max\
max。因此複雜度為o(n
k)
o(nk)
o(nk)。
#include
namespace iostream
template
<
typename t>
inline
void
read
(t &x)
template
<
typename t1,
typename..
.t2>
inline
void
read
(t1 &a, t2 &..
.x)inline
intreads
(char
*s)inline
void
ioflush()
inline
void
printc
(char c)
inline
void
prints
(char
*s)template
<
typename t>
inline
void
print
(t x,
char c =
'\n'
)else
printc
('0');
printc
(c);
}template
<
typename t1,
typename..
.t2>
inline
void
print
(t1 x, t2.
.. y)
}using
namespace iostream;
using
namespace std;
typedef
long
long ll;
const
int maxn =
20005
, maxk =
26000005
, maxm =
500005
;struct edge edge[maxn]
;int head[maxn]
, lim[maxn]
, val[maxn]
, sum[maxn]
, temp[maxm]
, tot, n, m, t;
int poolf[maxk]
, poolg[maxk],*
(f[maxn]),
*(g[maxn]
), par[maxn]
;void
addedge
(int u,
int v)
; head[u]
= tot;
}int que[maxm]
, ans;
void
dfs1
(int u,
int fa)
for(
int i = head[u]
; i; i = edge[i]
.next)
}void
dfs2
(int u,
int fa)if(
!head[u]
)for
(int i =
0; i <= m; i++
) ans =
max(ans, f[u]
[i]+ sum[u]
+ g[u]
[m - i]);
for(
int i =
0; i <= m; i++
) temp[i]
= g[u]
[i];
int*he = que +1,
*ta = que;
for(
int i =
0; i <= m; i++)}
intmain()
memset
(poolf,0,
sizeof
(poolf));
memset
(poolg,0,
sizeof
(poolg));
f[0]
= poolf, g[0]
= poolg;
for(
int i =
1; i <= n; i++
)dfs1(1
,0);
memset
(head,0,
sizeof
(head)
); tot =0;
for(
int i = n; i >
0; i--
)addedge
(par[i]
, i)
;dfs2(1
,0);
print
(ans);}
ioflush()
;return0;
}
樹形揹包 蘋果樹
題目大意 求乙個聯通點集點權和 m leq m m的最大點的個數。這道題是乙個樹形揹包問題,以點的個數為體積,以體積為價值 然後我們只要找到體積 m le m m的最大點數即可。我們設f i j f i j f i j 表示以i ii為根的子樹中,一定選第i ii個點且選了j jj個點的最小花費。若...
二叉蘋果樹 樹型DP 揹包
二叉蘋果樹 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 現在這顆樹枝條太多了,需要剪枝。但是一些樹...
二叉蘋果樹 樹形DP
題意 description 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1 現在這顆樹枝條太多了...