HDU 2844 Coins 解题报告 多重背包

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);
	}
}


发布了64 篇原创文章 · 获赞 0 · 访问量 1471

猜你喜欢

转载自blog.csdn.net/weixin_45566331/article/details/104223600