HDU 1011 星河戰隊 樹形DP

2022-05-09 19:11:31 字數 1265 閱讀 7066

題意是說在乙個洞穴中有許多房間,每個房間中有一些蟲子和大腦,這些房間之間用隧道相連形成一棵樹,士兵們殺蟲子的能力有限,也可以直接殺死蟲子而不消耗士兵戰鬥力,但這樣就無法得到房間中的大腦,士兵們不能走回頭路,問給定士兵數量時能得到的大腦最大值。

在樹上進行動態規劃,對於每個節點來說,選擇了它,就要損失士兵戰鬥力,不選擇它,就可以將這些省下來的士兵戰鬥力用在後面的房間中,後面的房間將最優選擇傳遞到當前位置,以此來判斷從而得到最優解。

轉移方程:dp[ i ][ j ] = max(dp[ i ][ j ], dp[ i ][ j-k ]+dp[ son(i) ][ k ])

dp[ i ][ j ] 表示以節點 i 為根節點時消耗 j 個士兵所能得到的最大大腦數。

開始的時候直接將每個士兵按戰鬥力分成每個戰鬥力為 1 的士兵,也就是說將士兵數量乘以 20 ,企圖直接可以用士兵數和蟲子數進行加減運算,但是這樣很明顯是錯誤的,因為如果乙個房間中的蟲子數模 20 不為零,也就是說並不能完全發揮乙個士兵的戰鬥力時,要取到這個房間的大腦,就需要再消耗乙個士兵,即士兵戰鬥力並不等於士兵手中的子彈數(這樣說好像更複雜了,意思就是每個士兵不一定會殺滿 20 只蟲子)。

還有一點就是士兵數是可以為零的,但是必須要有人進去才能得到大腦,無論裡面是否有蟲子。

**如下:

1 #include 2

using

namespace

std;

3const

int maxn = 110;4

intn,m;

5struct

node

6node[maxn];//

儲存所有節點上的資訊

9int dp[maxn][maxn];//

dp[i][j]表示根節點為 i 時,用掉 j 個士兵獲得的最大值

10int mp[maxn][maxn];//

存圖,mp[i][0]表示與節點 i 相連的邊的數目

11bool vis[maxn];//

記錄節點的訪問情況

12void dfs(int

root)

1327}28

intmain()

2947

if(m==0) puts("

0");//

有可能己方沒有士兵,但要求至少要有人進去

48else

495354}

55return0;

56 }

view code

這道題還是借鑑了很多大佬的部落格才做出來的,感謝這些大佬的分享 ^_^

hdu1011(揹包樹形DP)

沒有完全理解這題,m個人,攻打乙個map,map的入口是1,在攻打某個結點之前要先攻打其他乙個結點 dp i j 表示m個人攻打以第i個結點為根節點的子樹得到的最優解 狀態轉移dp i j max dp i j dp i k dp t j k 其中t是i結點的子節點 如下 include inclu...

hdu 1011 樹型DP(依賴揹包)

題意 你作為星河站隊的leader,手下有m個trooper 現在讓你去攻占乙個基地 有n個洞穴組成,入口是洞穴1,洞穴之間用n 1條邊鏈結,每個洞穴裡面包括x個 bugs,和他們的brains,你的每個trooper可以消滅20個bugs 問你最多可以得到多少個brains。需要注意的是 你沒做過...

HDU 1520 簡單樹形dp

題意 乙個大學要舉行職工party。為使party中每個人都玩的開心,直接上司和下屬關係的員工不能同時參加。每個人都有各自的歡樂值。問如何邀請使得總歡樂值最大。dp i 1 表示選擇i點 dp i 0 表示不選擇i點 include include include include using nam...