无限背包
一个在旅途中的长者有一个最多能装M公斤的背包;
现在有n种物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn;
输入n、m以及各种物品的重量和价值,求旅行者能获得最大总价值。
输入:
3 16 5 4 4 3 6 6
输出:
12
代码与01背包几乎一样,只是枚举的顺序不同而已。
01背包枚举容量时,从大到小,避免一个物品被选择多次;
无限背包枚举容量时,从小到大,允许一件物品没做选择多次。
#includeint n, m, i, j, k, w, v, f[105]; int main(){ freopen("wxbag.in", "r", stdin); scanf("%d%d", &n, &m); for(i=1; i<=n; i++){ scanf("%d%d", &w, &v); for(j=w; j<=m; j++){ if(f[j-w] + v > f[j]){ f[j] = f[j-w] + v; } } } printf("%dn", f[m]); return 0; }
多重背包
一个在旅途中的长者有一个最多能装M公斤的背包;
现在有n种物品,它们的重量分别是W1,W2,...,Wn,价值分别为V1,V2,...,Vn,数量分别为C1,C2,...,Cn;
输入n、m以及各种物品的重量、价值和数量,求旅行者能获得最大总价值。
输入:
3 16 5 4 2 4 3 5 6 6 1
输出:
12
多重背包,是指一个物品,可以选择多次;解法可以是将一件物品拆成多件物品。
如一件物品可以选择5次,那么我们可以看成是有5件那样的物品,做5次01背包即可。
#includeint n, m, i, j, k, w, v, c, f[105]; int main(){ freopen("dcbag.in", "r", stdin); scanf("%d%d", &n, &m); for(i=1; i<=n; i++){ scanf("%d%d%d", &w, &v, &c); while(c--){ for(j=m; j>=w; j--){ if(f[j-w] + v > f[j]){ f[j] = f[j-w] + v; } } } } printf("%dn", f[m]); return 0; }
混合背包
有的物品只能选1次,有的物品可以选择多次,有的物品可以选择很多次……混合在一起,就是混合背包。
如多重背包中,物品的数量c很大,那就好超时了;数量很大时,应转成无限背包去做。
#includeint n, m, i, j, k, w, v, c, f[105]; int main(){ freopen("dcbag.in", "r", stdin); scanf("%d%d", &n, &m); for(i=1; i<=n; i++){ scanf("%d%d%d", &w, &v, &c); if(c*w >= m){ for(j=w; j<=m; j++){ if(f[j-w] + v > f[j]){ f[j] = f[j-w] + v; } } } else{ while(c--){ for(j=m; j>=w; j--){ if(f[j-w] + v > f[j]){ f[j] = f[j-w] + v; } } } } } printf("%dn", f[m]); return 0; }
练习题
1 -- [C++一本通-动态规划]例9.12 完全背包
题目描述
设有n 种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为m,今从n 种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于m,而价值的和为最大。
输入
第1行:两个整数,m(背包容量,m<=200)和n(物品数量,n<=30);
第2至n+1行:每行两个整数Wi,Ci,表示每个物品的重量和价值。
输出
仅一行,一个数,表示最大总价值。
样例输入
10 4
2 1
3 3
4 5
7 9
样例输出
max=12
参考代码
#include
using namespace std;
const int qwq = 3000;
int m,n;
int w[qwq],v[qwq];
int dp[qwq][qwq];
int main() {
cin>>m>>n;
for(int i = 1; i <= n; i++) {
cin>>w[i]>>v[i];
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(j < w[i]) {
dp[i][j] = dp[i-1][j];
} else {
if(dp[i - 1][j] > dp[i][j - w[i]] + v[i]) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = dp[i][j - w[i]] + v[i];
}
}
}
}
cout<<"max="<
设有n 种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为m,今从n 种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于m,而价值的和为最大。
第1行:两个整数,m(背包容量,m<=200)和n(物品数量,n<=30);
第2至n+1行:每行两个整数Wi,Ci,表示每个物品的重量和价值。
仅一行,一个数,表示最大总价值。



