You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.6 KiB
67 lines
1.6 KiB
#include<bits/stdc++.h>
|
|
|
|
using namespace std;
|
|
|
|
/*
|
|
知识点内容:动态规划多重背包
|
|
|
|
文档内容参考:
|
|
https://www.cnblogs.com/aiguona/p/7274876.html
|
|
*/
|
|
#define MAX 1000000
|
|
using namespace std;
|
|
|
|
int dp[MAX]; //存储最后背包最大能存多少
|
|
int value[MAX], weight[MAX], number[MAX];//分别存的是物品的价值,每一个的重量以及数量
|
|
int bag;
|
|
|
|
void ZeroOnePack(int weight, int value)//01背包
|
|
{
|
|
int i;
|
|
for (i = bag; i >= weight; i--) {
|
|
dp[i] = max(dp[i], dp[i - weight] + value);
|
|
}
|
|
}
|
|
|
|
void CompletePack(int weight, int value)//完全背包
|
|
{
|
|
int i;
|
|
for (i = weight; i <= bag; i++) {
|
|
dp[i] = max(dp[i], dp[i - weight] + value);
|
|
}
|
|
}
|
|
|
|
void MultiplePack(int weight, int value, int number)//多重背包
|
|
{
|
|
if (bag <= number * weight)//如果总容量比这个物品的容量要小,那么这个物品可以直到取完,相当于完全背包
|
|
{
|
|
CompletePack(weight, value);
|
|
return;
|
|
} else//否则就将多重背包转化为01背包
|
|
{
|
|
int k = 1;
|
|
while (k <= number) {
|
|
ZeroOnePack(k * weight, k * value);
|
|
number = number - k;
|
|
k = 2 * k;//这里采用二进制思想
|
|
}
|
|
ZeroOnePack(number * weight, number * value);
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
int n;
|
|
while (~scanf("%d%d", &bag, &n)) {
|
|
int i, sum = 0;
|
|
for (i = 0; i < n; i++) {
|
|
scanf("%d", &number[i]);//输入数量
|
|
scanf("%d", &value[i]);//输入价值 此题没有物品的重量,可以理解为体积和价值相等
|
|
}
|
|
memset(dp, 0, sizeof(dp));
|
|
for (i = 0; i < n; i++) {
|
|
MultiplePack(value[i], value[i], number[i]);//调用多重背包,注意穿参的时候分别是重量,价值和数量
|
|
}
|
|
cout << dp[bag] << endl;
|
|
}
|
|
return 0;
|
|
} |