多重背包
题目:有 N 种物品和一个容量是 V 的背包。
第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。输出最大价值。
完全背包问题的扩展,把任意次放置的变量 k 上限改为 s[ i ]
for(int i = 1;i <= N;i ++)
for(int j = 1;j <= V;j ++)
for(int k = 0; k <= s[i-1] && k*v[i-1] <= j;k ++)
dp[i][j] = max(dp[i][j],dp[i-1][j-k*v[i-1]]+k*w[i-1]);
完整代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
/*
多重背包
每种物品可以选任意次,要求实现给定容积物品价值最大
*/
const int N = 4; //物品个数
const int V = 5; //背包容积
int w[N] = {2,4,4,5}; //物品价值
int v[N] = {1,2,3,4}; //物品体积
int s[N] = {3,1,3,2}; //物品个数限制
int knapsack(){
//dp[i][j]是考虑前i件物品并且体积为j时的价值量最优解
vector<vector<int> > dp(N+1,vector<int>(V+1)); //dp初始化
for(int i = 1;i <= N;i ++)
for(int j = 1;j <= V;j ++)
for(int k = 0; k <= s[i-1] && k*v[i-1] <= j;k ++) //在容积范围内最多放s[i]个数范围的i物品与之前的价值量对比
dp[i][j] = max(dp[i][j],dp[i-1][j-k*v[i-1]]+k*w[i-1]);
//打印状态转移矩阵
for(int i = 1;i <= N;i ++){
for(int j = 1;j <= V;j ++) cout<<dp[i][j]<<" ";
cout<<endl;
}
//返回结果
return dp[N][V];
}
int main(){
cout<<knapsack();
}
运行结果: