Vijos1676 陶陶吃蘋果(樹形dp)

2021-08-17 04:41:30 字數 1887 閱讀 4633

題目鏈結

分析:

好好讀題啊

如果乙個點被保留,那麼這個點到根路徑上的點都會被保留,前輩說這是:樹形依賴問題

解決樹形依賴問題的常見做法就是將父節點的值給當前節點,然後用當前節點繼續深層的計算 設f

[i][

j]f [i

][j]

表示在結點

i i

到根結點的鏈一側選擇

j' role="presentation" style="position: relative;">j

j個結點的最大收益 f[

son]

=f[x

] f[s

on]=

f[x]

,然後用遞迴後的f[

son]

f [s

on]更新f[

x]f [x

]f[x

][i]

=max

(f[s

on][

i−1]

+a[s

on],

f[x]

[i])

f [x

][i]

=max

(f[s

on][

i−1]

+a[s

on],

f[x]

[i])

考慮這道題,t−

h<=

k t−h

<=

k的限制實際上就是白送了你一條鏈(鏈上結點數-高度一定等於零)

那麼我們可以對於每一條鏈預處理出鏈左右兩側的貢獻,那麼答案實際上就是除了這條鏈,選擇

m m

個結點的最大收益

統計答案時,對於乙個葉子結點x

列舉左側選擇了

i' role="presentation" style="position: relative;">i

i個結點(右側就選擇了m−

i m−i

個結點)

該情況的答案即為f[

x][i

]+g[

x][m

−i]+

x到根的

鏈總和 f[x

][i]

+g[x

][m−

i]+x

到根的鏈

總和

#include

#include

#include

using namespace std;

const int n=5010;

int sum[n],n,m,c[n],root,du[n],nxt[n][n];

int f[n][510],g[n][510];

void dfs_1(int now)

}void dfs_2(int now)

}int main()

sum[root]=c[root];

dfs_1(root);

dfs_2(root);

int ans=0;

for (int i=1;i<=n;i++) if (!du[i])

for (int j=0;j<=m;j++)

ans=max(ans,f[i][j]+g[i][m-j]+sum[i]);

printf("%d\n",ans);

return 0;

}

裝箱問題 vijos

有乙個箱子容量為v 正整數,o v 20000 同時有n個物品 o n 30 每個物品有乙個體積 正整數 要求從 n 個物品中,任取若千個裝入箱內,使箱子的剩餘空間為最小。第一行,乙個整數,表示箱子容量 第二行,乙個整數,表示有n個物品 接下來n行,分別表示這n個物品的各自體積。乙個整數,表示箱子剩...

vijos 積木城堡

恰似今天更了七章 我該怎麼辦 看上去好像只能瘋狂寫揹包啦 他們說周四化學通練,我好慌 描述 第一行是乙個整數n n 100 表示一共有幾座城堡。以下n行每行是一系列非負整數,用乙個空格分隔,按從下往上的順序依次給出一座城堡中所有積木的稜長。用 1結束。一座城堡中的積木不超過100塊,每塊積木的稜長不...

Vijos 河蟹王國

河蟹王國有一位河蟹國王,他的名字叫羊駝。河蟹王國富饒安定,人們和諧相處。有一天,羊駝國王心血來潮,想在一部分人中挑出最和諧的人。於是,羊駝國王將他的子民排成了一列 b汗 好長呀 每個人都有乙個初始的和諧值。羊駝國王每次會選擇乙個區間 l,r 這個區間中和諧值最大的人就是國王選出的人。而且,在某一時間...