下面就是多重揹包的原題(借用洛谷的)
終於,破解了千年的難題。小ff找到了王室的寶物室,裡面堆滿了無數價值連城的寶物……這下小ff可發財了,嘎嘎。但是這裡的寶物實在是太多了,小ff的採集車似乎裝不下那麼多寶物。看來小ff只能含淚捨棄其中的一部分寶物了……小ff對洞穴裡的寶物進行了整理,他發現每樣寶物都有一件或者多件。他粗略估算了下每樣寶物的價值,之後開始了寶物篩選工作:小ff有乙個最大載重為w的採集車,洞穴裡總共有n種寶物,每種寶物的價值為v[i],重量為w[i],每種寶物有m[i]件。小ff希望在採集車不超載的前提下,選擇一些寶物裝進採集車,使得它們的價值和最大。
輸入格式:
第一行為乙個整數n和w,分別表示寶物種數和採集車的最大載重。
接下來n行每行三個整數,其中第i行第乙個數表示第i類品價值,第二個整數表示一件該類物品的重量,第三個整數為該類物品數量。
輸出格式:
輸出僅乙個整數ans,表示在採集車不超載的情況下收集的寶物的最大價值。
輸入樣例#1:
4 20
3 9 3
5 9 1
9 4 2
8 1 3
輸出樣例#1:對於30%的資料:n≤∑m[i]≤10^4;0≤w≤10^3。
對於100%的資料:n≤∑m[i]≤10^5;
0 這一道題又兩種做法,一種是被倍增,另一種是單調佇列
前者相信大家都會,我就不講了,後者我看了很多部落格,他們都寫的我一臉懵逼
我研究了好久,終於知道怎麼做了
首先定義乙個dp陣列
dp[i]表示到達i重量時的最大值
列舉1-n
對於當前的寶物,它的意義就是更新陣列,所以我們至少要用到乙個
舉個栗子,假設當前的寶物重量為3,數量為3,價值不說(在這個栗子中沒有意義)
用乙個指標j從1一直到w,假設現在指到w-1,那麼就是這樣繼承的
我們給這些格仔分乙個組,按照每w個為一組,這個繼承的狀態就十分的明顯了
dp[j]=max(dp[j-k*w]+k*v) (1<=k<=w)
因為分了組,每一組中相同位置的繼承有幾分相似,感覺就可以用單調佇列了
可是因為公式k*v的阻礙,所以現在還不能用單調佇列
所以我們可以考慮把公式改一改
假如當前的位置是r,要繼承l
那麼需要找出(r-l)有多少個v,我們本來想的是先把(r-l)算出,然後再算v
利用整式乘法,可以先找出r中v的個數,再減去l中v的個數
所以我們就可以巧妙的把r消去,從而進行單調佇列的優化
**就是先把所有位置除以w以後,餘數相同的取出來一起算
我後面可能講的不是很明白,但是你們看圖就能明白是什麼意思了
更加清晰詳細的**在後面
#include#includeusing namespace std;
inline int read()
inline void print(int x)
const int n=4e4+10;
int n,w;
int ans,maxx,dp[n];
int head,tail;
struct nodelist[n];
int main()//如果w是0,就不用在算了
for(int j=0;j=list[tail].x)tail--;//入隊
list[++tail]=(node);
while(head<=tail&&list[head].p
dp[j+k*w]=max(dp[j+k*w],list[head].x+k*v);// 算出dp[j+k*w]
maxx=max(maxx,dp[j+k*w]);//記錄最大值
} }
}print(maxx+ans);//不要忘記加上ans哦
return 0;
}
python多重揹包 多重揹包
多重揹包問題 有 n 種物品和乙個容量是 v 的揹包。第 i 種物品最多有 si 件,每件體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。輸出最大價值。資料範圍 0 n v 100 0 vi wi si 100 樸素版多重揹包問題 樸素版完全揹包問...
多維多重揹包問題 01揹包,完全揹包,多重揹包
csdn 專業it技術社群 登入 blog.csdn.net有n件物品和乙個容量為v的揹包。第i件物品的費用是w i 價值是v i 求將哪些物品裝入揹包可使價值總和最大。1.1空間優化 這要求在每次主迴圈中我們以 v v 0 的遞減順序計算 f v 這樣才能保證計算 f v 時 f v ci 儲存的...
揹包學習 多重揹包揹包
有n種物品和乙個容量為v的揹包。第i種物品最多有n i 件可用,每件費用是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。狀態轉移方程 f i v max 此時他面臨的不是01揹包的選與不選的問題,而是從n i 裡面選多少個的問題。實現方法 1 轉化...