HDU 2844 Coins 解题报告 多重背包
思路和这个链接里的基本一样:https://blog.csdn.net/weixin_45566331/article/details/104224577
板子都是一样的,改下就行
解题思路:多重背包+二进制优化。具体解释上面链接里已经很详细了。
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#pragma warning(disable:4996)
#define INF 0x3f3f3f3f
#define ll long long
#define PI acos(-1.0)
const int N = 1000010;
const int maxn = 1e9;
using namespace std;
int dp[100005];
int v[105];
int num[105];
int n, m;
void zero(int cost)//01背包
{
for (int i = m; i >= cost; i--)
{
dp[i] = max(dp[i], dp[i - cost] + cost);
}
}
void complet(int cost)//完全背包
{
for (int i = cost; i <= m; i++)
{
dp[i] = max(dp[i], dp[i - cost] + cost);
}
}
void multi(int cost, int amount)//多重背包
{
if (cost * amount >= m)
{
complet(cost);
return;
}
int k = 1;
while (k < amount)
{
zero(k * cost);
amount -= k;
k <<=1;
}
zero(amount * cost);
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
if (n == 0 && m == 0)
break;
memset(dp, -INF, sizeof(dp));
dp[0] = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d", &v[i]);
}
for (int i = 1; i <= n; i++)
{
scanf("%d", &num[i]);
}
for (int i = 1; i <= n; i++)
{
multi(v[i], num[i]);
}
int cnt = 0;
for (int i = 1; i <= m; i++)
{
if (dp[i] > 0)
cnt++;
}
printf("%d\n", cnt);
}
}