多重揹包問題

2021-07-23 10:53:41 字數 1055 閱讀 3322

來自《挑戰程式設計競賽》

有n中物品,它們的重量和價值分別是w[i]和v[i]。現在要從中選出一些物品使得總重量不超過w,並且價值的總和最大。不過要求第i中物品最多可以選m[i]個。

資料範圍

1<=n<=100,1<=w[i],v[i]<=100,1<=m[i]<=10000,1<=w<=10000

這是乙個有個數限制的問題,對於每個物品至多選乙個或者可以選任意個的問題我們已經在o(nw)時間內求解。如果使用同樣的方法解答本題,則狀態轉移方程為:

dp[i][j]:從編號為0到編號為i-1,前i個物品總重量不超過j的所有選法中最大可能的價值。

有dp[0][j]=0;dp[i+1][j]=max。

如果使用這個狀態轉移方程,時間複雜度就是o(nmw)。

int n,w;

int w[maxn],v[maxn],m[maxn];

int dp[maxn][maxw];

void solve()

for(int i=0;i=k*w[i];k++)}}

printf("%d\n",dp[n][w]);

}

這個演算法時間複雜度較高,無法在規定時間內求解。

我們把m[i]分解成如下形式:m[i]=1+2+2^2+……2^k+a(0<=a<2^(k+1))

由於1,2,2^2,……2^k可以表示出0~2^(k+1)-1的所有整數,因此,1,2,2^2,……2^k,a可以表示出0~m[i]的所有整數。因此,我們可以把m[i]個重量和價值分別是w[i],v[i]的物品看成重量和價值分別是w[i]*x,v[i]*x(x=1,2,2^2,……,2^k,a)的k+2個物品,這樣物品的總數就變為o(nlogm)個,使用一般的01揹包dp可以在o(nwlogm)時間內求出答案。

int n,w;

int w[maxn],v[maxn],m[maxn];

int dp[maxw];

void solve()

num-=mul;}}

printf("%d\n",dp[w]);

}

多維多重揹包問題 多重揹包問題

悼念512汶川大 遇難同胞 珍惜現在,感恩生活 急!災區的食物依然短缺!為了挽救災區同胞的生命,心繫災區同胞的你準備自己採購一些糧食支援災區,現在假設你一共有資金n元,而市場有m種大公尺,每種大公尺都是袋裝產品,其 不等,並且只能整袋購買。請問 你用有限的資金最多能採購多少公斤糧食呢?後記 人生是乙...

揹包問題 多重揹包

有n種物品和乙個容量為w的揹包。第i種物品最多有n i 件可用,每件重量是w i 價值是v i 求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。1.使用三重迴圈進行遞推 狀態轉移式為 dp i j max 關鍵 如下 void solve printf d n dp n ...

多重揹包問題

有n種物品和乙個容量為v的揹包。第i種物品最多有n i 件可用,每件費用是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。這題目和完全揹包問題很類似。基本的方程只需將完全揹包問題的方程略微一改即可,因為對於第i種物品有n i 1種策略 取0件,取1件...