bzoj4247 掛飾 揹包dp

2022-05-20 10:57:43 字數 1010 閱讀 5885

題目描述

joi君有n個裝在手機上的掛飾,編號為1...n。 joi君可以將其中的一些裝在手機上。

joi君的掛飾有一些與眾不同——其中的一些掛飾附有可以掛其他掛件的掛鉤。每個掛件要麼直接掛在手機上,要麼掛在其他掛件的掛鉤上。直接掛在手機上的掛件最多有1個。

此外,每個掛件有乙個安裝時會獲得的喜悅值,用乙個整數來表示。如果joi君很討厭某個掛飾,那麼這個掛飾的喜悅值就是乙個負數。

joi君想要最大化所有掛飾的喜悅值之和。注意不必要將所有的掛鉤都掛上掛飾,而且乙個都不掛也是可以的。

輸入第一行乙個整數n,代表掛飾的個數。

接下來n行,第i行(1<=i<=n)有兩個空格分隔的整數ai和bi,表示掛飾i有ai個掛鉤,安裝後會獲得bi的喜悅值。 

輸出輸出一行乙個整數,表示手機上連線的掛飾總和的最大值

樣例輸入

50 4

2 -2

1 -1

0 10 3

樣例輸出5題解

揹包dp

根據題意很容易想到dp狀態:f[i][j]表示從前i個物品中選擇某些物品,使得剩下的掛鉤數量為j的最大喜悅值。

但是這樣會tle。

思考:乙個物品,最多隻會消耗1個掛鉤。因此如果已經有了大於等於超過n個掛鉤,說明全部物品都可以掛上,記錄過多的狀態也就沒有了意義。

所以我們把j的上界設為n即可,dp時取j+ai和n的最小值作為狀態即可。

注意要先按照掛鉤數量從大到小排序(其實不排序也行,就是會比較麻煩)

**中把狀態壓到了一維,需要注意一下更新順序啥的。

#include #include #include #define n 2010

using namespace std;

struct data

w[n];

int f[n];

bool cmp(data x , data y)

int main()

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

return 0;

}

BZOJ 4247 掛飾 揹包DP

貪心的想法 在保證正確性的情況下盡量多的掛鉤。所以我們先把每個掛飾按照掛鉤數量從大到小排序。f i j f i j f i j 表示排序後的前i ii個物品在有j jj個掛鉤的情況下的最大價值之和。那麼對於第i ii個物品,無非就是選擇與否的關係,樸素的轉移。而對於貪心要保證的正確性,我們在狀態轉移...

BZOJ 4247 掛飾 01揹包

joi君有n個裝在手機上的掛飾,編號為1.n。joi君可以將其中的一些裝在手機上。joi君的掛飾有一些與眾不同 其中的一些掛飾附有可以掛其他掛件的掛鉤。每個掛件要麼直接掛在手機上,要麼掛在其他掛件的掛鉤上。直接掛在手機上的掛件最多有1個。此外,每個掛件有乙個安裝時會獲得的喜悅值,用乙個整數來表示。如...

BZOJ 4247 掛飾(揹包變形)

雖然轉移方程可以一眼看出 但是煩就煩在為何要排序 有人說這是乙個貪心,又有人說這是乙個保障正確性的。就按照貪心的想法好了 在保證正確性的情況下盡量多的掛鉤。include define n 2005 define inf 0x3f3f3f3f using namespace std int n,f ...