题目描述
一个旅行者有一个最多能负载m公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分
输入格式
第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30); 第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。
别为C1,C2,...,Cn.若每种物品只有一件求旅行者能获得最大总价值。
输出格式
仅一行,一个数,表示最大总价值。
题解
这是一道动态规划题,首先他让我们求能装下且总价值是最大。
先设一个二维数组a[背包数量i][背包剩余空间j]=背包最大价值。两层循环,1-n和1-m
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
}
}
第一种情况
接着判断j是否小于w[i],也就是每个物品的重量是否大于j,为什么要是否大于j呢?
因为这是要看背包是否能装下这件物品了,而如果装不下,那么这一个背包和上一个背包的价值是一样的!!当遇到这种情况:就a[i][j](当前背包)=a[i-1][j](上一个背包)
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if (j < w[i]) {
a[i][j] = a[i - 1][j]; //新增
}
}
}
第二种情况
如果能装下的话,那么就又分两种情况了:
如果前一个背包的价值要大于前一个背包的价值+当前物品的价值-当前物品的重量的话,那就不值得了,所以这种情况,和上面一样:a[i][j](当前背包)=a[i-1][j](上一个背包)
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if (j < w[i]) {
a[i][j] = a[i - 1][j];
}
else {
if (a[i - 1][j] > a[i - 1][j - w[i]] + c[i]) {
a[i][j] = a[i - 1][j]; //新增
}
}
}
但是还有另一种情况:
如果前一个背包的价值要小于前一个背包的价值+当前物品的价值-当前物品的重量的话,那肯定值啊!!!
重点(吗?):
不是,也很好理解
就是前一个背包的价值+当前物品的价值-当前物品的重量赋值给当前背包(和上面的判断条件一样)即:
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if (j < w[i]) {
a[i][j] = a[i - 1][j];
}
else {
if (a[i - 1][j] > a[i - 1][j - w[i]] + c[i]) {
a[i][j] = a[i - 1][j];
else {
a[i][j] = a[i - 1][j - w[i]] + c[i]; //新增
}
}
}
}
怎么样很好理解吧~~~
给出所有代码!!!(主页解释)
#include <bits/stdc++.h>
using namespace std;
int m, n, w[35], c[35], a[1005][1005];
void f__() {
int i, j;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (j < w[i]) {
a[i][j] = a[i - 1][j];
} else {
if (a[i - 1][j] > a[i - 1][j - w[i]] + c[i]) {
a[i][j] = a[i - 1][j];
} else {
a[i][j] = a[i - 1][j - w[i]] + c[i];
}
}
}
}
}
int main() {
cin >> m >> n;
for (int i = 1; i <= n; i++) cin >> w[i] >> c[i];
f_();
cout << a[n][m];
return 0;
}
什么?没学过函数?(前面有字)
没学过函数凑什么热闹!!,这不诚心想气我吗这不是?(作为惩罚:必须点赞)
点赞你要亮,关注干得漂亮
不关注点赞你就别走
每天必须日更!!