題目描述【問題描述】在《Harry Potter and the Deathly Hallows》中,Harry Potter他們一起逃亡,現在有許多的東西要放到赫敏的包裡面,但是包的大小有限,所以我們只能夠在裡面放入非常重要的物品,現在給出該種物品的數量、體積、價值的數值,希望你能夠算出怎樣能使背包的價值最大的組合方式,並且輸出這個數值,赫敏會非常地感謝你。出自:宜昌一中【資料規模】對於30%的資料1<=v<=5001<=n<=20001<=m<=101<=w<=201<=s<=100對於100%的資料1<=v<=5001<=n<=20001<=m<=50001<=w<=201<=s<=100輸入格式【輸入】(1)第一行有2個整數,物品種數n和背封裝載體積v。(2)2行到n+1行每行3個整數,為第i種物品的數量m、體積w、價值s。.輸出格式【輸出】僅包含一個整數,即為能拿到的最大的物品價值總和。範例輸入【輸入範例】 2 10 3 4 3 2 2 5範例輸出【輸出範例】 13 【注釋】選第一種一個,第二種兩個。結果為3*1+5*2=13
簡單的一道多重背包,不再多說。
注意枚舉的時候,分成兩種情況:
若某個物品數量乘以單位體積超過背包總容量,則當成完全背包處理;否則將這個物品的數量拆成二進制數,再按零壹背包的方式枚舉這個二進制數的每一位。
ACCode:
#include <cstdio>#include <cstring>#include <bitset>#include <cstdlib>using std::max;const char fi[] = "rqnoj98.in";const char fo[] = "rqnoj98.out";const int maxN = 2010;const int maxV = 510;const int MAX = 0x3fffff00;const int MIN = -0x3fffff00;int f[maxV];int a[maxN];int w[maxN];int v[maxN];int n, m; void init_file() { freopen(fi, "r", stdin); freopen(fo, "w", stdout); } void readdata() { scanf("%d%d", &n, &m); for (int i = 1; i < n + 1; ++i) scanf("%d%d%d", a + i, w + i, v + i); } void work() { for (int i = 1; i < n + 1; ++i) { if (a[i] * w[i] >= m) for (int j = w[i]; j < m + 1; ++j) f[j] = max(f[j], f[j - w[i]] + v[i]); else { for (int k = 1; k < a[i]; k <<= 1) { for (int j = m; j >= k * w[i]; --j) f[j] = max(f[j], f[j - k * w[i]] + k * v[i]); a[i] -= k; } for (int j = m; j >= a[i] * w[i]; --j) f[j] = max(f[j], f[j - a[i] * w[i]] + a[i] * v[i]); } } printf("%d", f[m]); } int main(){ init_file(); readdata(); work(); exit(0);}