题目描述
有一个包和n个物品,包的容量为m,每个物品都有各自的体积和价值,问当从这n个物品中选择多个物品放在包里而物品体积总数不超过包的容量m时,能够得到的最大价值是多少?[对于每个物品不可以取多次,最多只能取一次,之所以叫做01背包,0表示不取,1表示取]
输入
输入数据第一行包括两个整数m和n(1<m<10000,1<n<100) 分别表示为背包的容积为和物品的数量。
接下来第n行,每一行包括输入两个整数ai,bi,分别表示第i个物品的体积和价值
输出
当从这n个物品中选择多个物品放在包里而物品体积总数不超过包的容量m时,能够得到的最大价值。
样例输入 Copy
100 5
77 92
22 22
29 87
50 46
99 9
样例输出 Copy
133
#include <iostream>
#include <string.h>
using namespace std;
const int MAX = 1024;
int n; //物品个数
int c; //包的容量
int value[MAX]; //物品的价值
int weight[MAX]; //物品的重量
int x[MAX]; //n元0-1向量
int m[MAX][MAX]; //解的容器
void Input()
{
cin >> c >> n;
for (int i = 1; i <= n; ++i)
cin >> weight[i] >> value[i];
}
//创建最优解
void Knapsack()
{
memset(m, 0, sizeof(m));
for (int i = 1; i <= n; ++i) //逐行填表,i表示当前可选物品数,j表示当前背包的容量, 也就是从低到顶。
{
for (int j = 1; j <= c; ++j)
{
if (j < weight[i])
m[i][j] = m[i - 1][j];
else
{
m[i][j] = max(m[i - 1][j], m[i - 1][j - weight[i]] + value[i]);
}
}
}
}
//获取最优解(即设法将求得的最优解输出出来)
void Traceback()
{
int cc = c;
for (int i = n; i > 1; --i)
{
if (m[i][cc] == m[i - 1][cc])
x[i] = 0;
else
{
x[i] = 1;
cc -= weight[i];
}
}
if (cc >= weight[1])
x[1] = 1;
}
void Output()
{
cout << m[n][c] << endl;
}
int main()
{
Input();
Knapsack();
Traceback();
Output();
}