洛谷P1776 寶物篩選

2022-02-16 15:49:47 字數 1987 閱讀 8456

題目描述

終於,破解了千年的難題。小 ff 找到了王室的寶物室,裡面堆滿了無數價值連城的寶物。

這下小 ff 可發財了,嘎嘎。但是這裡的寶物實在是太多了,小 ff 的採集車似乎裝不下那麼多寶物。看來小 ff 只能含淚捨棄其中的一部分寶物了。

小 ff 對洞穴裡的寶物進行了整理,他發現每樣寶物都有一件或者多件。他粗略估算了下每樣寶物的價值,之後開始了寶物篩選工作:小 ff 有乙個最大載重為w的採集車,洞穴裡總共有n種寶物,每種寶物的價值為vi,重量為wi,每種寶物有mi件。小 ff 希望在採集車不超載的前提下,選擇一些寶物裝進採集車,使得它們的價值和最大。

輸入格式

第一行為乙個整數n和w,分別表示寶物種數和採集車的最大載重。接下來n行每行三個整數vi,wi,mi。

輸出格式

輸出僅乙個整數,表示在採集車不超載的情況下收集的寶物的最大價值。

輸入輸出樣例

輸入:420

3935

9194

2813

輸出:27

下面就是這道題的題解!

這道題好像就是多重揹包

多重揹包有很多種思路去做,我會的一共有兩種:

第一種是把多重揹包看成是01揹包來做 

就直接說這個題,每種寶物有乙個或者多個,我們可以把這多個看成是不同的物體,這樣就是乙個普通的01揹包問題

但是嘞,這麼做時間複雜度會暴增,肯定會爆掉幾個點所以這個問題就不能用這個方法去做

所以直接進入下個方法:

這個方法用到了二進位制的思想

怎麼碩呢

舉個例子,乙個數13,有這麼幾個數:1,2,4,8,16...(我絕對不會告訴你這是以2為底數的冪)

要求用這些數湊齊13,很簡單1+4+8=13,

其他的任何正整數都可以湊出來,為什麼呢?

把這些以2為底數的冪全部用2進製表示:

1->1

2->10

4->100

8->1000

然後來湊數x

x用二進位制來表示肯定是1和0組成的,然後看上面的數,每乙個以2為底數的冪都在每個二進位制位上有乙個單獨的1,其他都是0

也就是說,所有1和0的組合都能夠加出來

所以,以2為底數的冪相加可以湊出任何乙個正整數。

好了,證明完了,現在做題

在這個題目中,我們可以不把寶物數量分成乙個乙個的,而是分成上面所說的數字

這樣時間複雜度會大大降低。

下面直接上**(資料很水,這種非最優方法就能過)

#include#include

#include

#include

#include

#define inf 100000000

using

namespace

std;

//狀態:dp[i][j]表示前i個物品占用體積為j時所獲得的的最大價值。

//轉移方程:dp[i][j]=max(dp[i-1][j]

//dp[i-1][j-w[i]]+v[i]

//........

//dp[i-1][j-n[i]*w[i]]+n[i]*v[i])

//複雜度:o(σlogn[i]*m)

int n0,v0,w0,v[100001],w[100001],dp[1001][1001

]; int

main()

if(n0!=0

)

}for(int i=1;i<=d;i++)

for(int j=v;j>=0;j--)

int ans=0

;

for(int i=0;i<=v;i++)

cout

}

最後祝大家ac所有題!

給個贊再走唄?

洛谷P1776 寶物篩選

當年在tb桌前跪著聽懂了單調佇列優化多重揹包 然後那天下午codevs上的多重揹包一直過不去 現在codevs沒了,時間過得真快,有點心酸,當年bzoj也不知道,全在codevs上做題,好多 記錄都沒了。今天突然發現這題補掉,舒服了 includeusing namespace std const ...

洛谷p1776寶物篩選

寶物篩選 多重揹包問題 物品數目已知 可以列舉每個物品 當做01揹包來做 不過會超時 此時需要二進位制拆分來優化 分解成新的物品 再跑一遍01揹包即可 二進位制拆分 01揹包 設f j 表示前i件物品花費恰好為j的最大價值 include include using namespace std co...

洛谷P1776 寶物篩選

題目大意 n種物品,揹包有容量w。現在每個物品價值p,重量v,數量k,求揹包能放物品的最大價值。解題思路 多重揹包問題。然而貌似直接列舉k是會超時的,所以需要加上優化。我們把每個k拆成 2 0 2 1 2 2 2 n x 的形式,然後進行揹包。容易知道,這樣拆分出的物品能保證選取其中若干個相加可以的...