LuoguP1273有線電視網 樹形依賴揹包

2022-05-31 08:00:11 字數 1963 閱讀 8144

參考**

參考一篇寫的很好的博文

題目鏈結

首先確定泛化物品的定義:價值隨著體積變化的物體,如01揹包中的f[i](體積為i時的最大價值最f[i])。

泛化物品+普通物品:

還是01揹包,我們是怎麼在泛化物品f[i]中加入乙個體積為v,價值為w的普通物品的?

f[i]=max(f[i],f[i-v]+w);

o(n)解決。

分析題目:可以看作是葉子節點的v=1,非葉子節點的v=0,w=父親到該點的費用*(-1)+該點的money。就是乙個樹形依賴模型,每個節點是乙個物品。

設f[i][j]表示dfs序小於等於節點i的所有節點(物品)中,體積為j時的最大價值。

設s為i的乙個孩子。

則f[i]管理的範圍為紅色圈,f[s]管理的範圍為藍色圈。

從上往下(父親-->孩子)dfs時,先讓f[s]=f[i](s繼承i的全部資訊)

強制讓f[s]必須選擇s,然後往下對s進行dp。

讓f[s]必須選普通物品s是因為選擇了s才能選s的孩子:f[s]=f[i]; f[s][j]=max(f[s][j],f[s][j-v]+w);就是說,f[s]=f[i]+物品s

如果不是選擇孩子之前必須選擇父親:f[s]=max(f[i],f[i]+物品s)

回溯(孩子-->父親)時:將f[s]與f[i]合併。

泛化物品的並: 因為兩個泛化物品之間存在交集,所以不能同時兩者都取,那麼我們就需要求 泛化物品的並,對同一體積,我們需要選取兩者中價值較大的一者,效率 o(c)。

我的**以及注釋:

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;78

const

int n=3010,inf=(int

)1e9;

9struct

nodea[2*n];

12int

len,n,m;

13int

first[n],v[n],w[n],f[n][n],cost[n];

1415

int maxx(int x,int y)

1617

void ins(int x,int y,int

d)18

2324

void

init()

2537}38

for(int i=n-m+1;i<=n;i++) scanf("

%d",&w[i]);

39for(int i=1;i<=n-m;i++) v[i]=0;40

for(int i=n-m+1;i<=n;i++) v[i]=1;41

}4243void dfs(int x,int

fa)4454}

55}5657

void dp(int x,int

fa)5875}

7677

7879

intmain()

8094 printf("

0\n"

);95

return0;

96 }

題解 P1273 有線電視網

這題顯然是個樹形dp之樹上分組揹包,信心滿滿地寫出轉移方程後,發現 時間複雜度 o n 3 但仔細觀察了討論區和題解後,發現,這是 o n 2 的?於是我開始嘗試牙刷圖 分塊牙刷圖 菊花圖 掃帚圖。卡標算。燃鵝失敗了。證明 暫且先認為所有節點都會產生貢獻,這不會影響最壞複雜。考慮一下最裡面迴圈的過程...

有線電視網 洛谷p1273

某收費有線電視網計畫轉播一場重要的足球比賽。他們的轉播網和使用者終端構成一棵樹狀結構,這棵樹的根結點位於足球比賽的現場,樹葉為各個使用者終端,其他中轉站為該樹的內部節點。從轉播站到轉播站以及從轉播站到所有使用者終端的訊號傳輸費用都是已知的,一場轉播的總費用等於傳輸訊號的費用總和。現在每個使用者都準備...

有線電視網 洛谷 P1273

只能想到n 3的辦法 一看資料量自閉了。看了題解也是n 3 智障出題人 dp i j 代表以i為根的子樹選j個使用者時得到的最大收益 然後就是樹上揹包轉移一下 最後看根節點上最多選幾個人不虧本 include include include using namespace std const int...