2019暑期集训-【HDU 1114】完全背包 Piggy-Bank

题目链接:传送门

题意:

告诉你背包的容量N,和 M 件物品分别各自的体积和质量, 求背包剩余容量为0(即刚好填满)的时候,最小的质量。

3   三个测试样例 

10 110  //N = 110 - 10 = 100  题意为金元宝总质量110 金元宝自己的质量为10 所以物品的质量就是100

2  // 两件物品

1 1  //质量为1  体积为1

30 50  // 质量为30 体积为50

所以放两个体积50的就满了  质量最少 为 60 

所以输出 The minimum amount of money in the piggy-bank is 60.

1 6

2

10 3

20 4

第三个例子同理  背包体积为5  物品体积为3 4 ,肯定放不满,所以输出不可能。

分析:

    这个题目是完全背包的模板题,可完全背包非常类似于01背包问题,所不同的是每种物品有无限件。也就是从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取0件、取1件、取2件……等很多种。如果仍然按照解01背包时的思路,令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值。仍然可以按照每种物品不同的策略写出状态转移方程,像这样:

f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v}

模板是这样的:

for i=1..N
    for v=0..V
        f[v]=max{f[v],f[v-cost]+weight}

所以只需要套一下模板,注意初始化必须要大一点  99999会WA

求背包最大重量,初始化0 ,状态转移方程取max

求背包最小重量,初始化+∞,状态转移方程取min

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int minn(int x, int y) {
	return x < y ? x : y;
}
const int INF = 99999999;
struct ss
{
	int zhong;
	int ti;
}a[502];
int dp[10002];
int main()
{
	int t;
	scanf_s("%d", &t);
	while (t--) {
		int n, m;
		scanf_s("%d%d", &n, &m);
		n = m - n;
		scanf_s("%d", &m);
		for (int i = 0; i < m; i++) {
			scanf_s("%d%d", &a[i].zhong, &a[i].ti);
		}
		fill(dp, dp + 10002, INF);
		dp[0] = 0;
		for (int i = 0; i < m; i++) {
			for (int j = a[i].ti; j <= n; j++) {
				dp[j] = minn(dp[j], dp[j - a[i].ti] + a[i].zhong);
			}
		}
		if (dp[n] == 99999999)
			puts("This is impossible.");
		else
			printf("The minimum amount of money in the piggy-bank is %d.\n", dp[n]);
	}
	return 0;
}
发布了42 篇原创文章 · 获赞 26 · 访问量 9585

猜你喜欢

转载自blog.csdn.net/qq_41464123/article/details/95653282
今日推荐