HDU 1114 Piggy-Bank

传送门

完全背包。求最小价值(恰好装满)。

有一个存钱罐,里面有很多个硬币,硬币分为很多种类,每种有各自的重量和价值。现在给你每种硬币的信息,和这个存钱罐存的重量,让你猜测里面硬币的最小价值。

这个题让求最小价值,所以肯定是必须装满了(结合这个题意也必须是重量恰好相等)。最小值一定是必须装满,但必须装满不一定是求最小值。

必须装满的话,初始化置为-INF就可以了,但是还是个最小值问题,最小值问题是min函数,所以初始化不可能的情况为+INF。然后最后判断dp[V],如果正好等于+INF就说明不可能恰好装满。(为什么最后还是正好等于+INF?因为 min(INF,INF+p[i]) = INF。如果是最大值的恰好装满就要判断dp[V]是否小于0

另外,因为是恰好装满问题,我感觉用不了那个优化,就是对物品预处理,删一些物品的那个优化。


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
using namespace std;  // 完全背包 求最小值(恰好装满)

const int MAXN = 501;
const int INF = 1e9;
int dp[10001];
int p[MAXN];
int w[MAXN];
int N, V, T;

void init()
{
	fill(dp + 1, dp + V + 1, INF);   // 是求最小值,所以不可能情况的初始值设为 +INF
	dp[0] = 0;
}

int main()
{
	int a, b;
	scanf("%d", &T);
	for (; T--;)
	{
		scanf("%d%d", &a, &b);
		V = b - a;
		init();
		scanf("%d", &N);
		for (int i = 1; i <= N; i++)
			scanf("%d%d", &p[i], &w[i]);

		for (int i = 1; i <= N; i++)
		{
			for (int j = w[i]; j <= V; j++)      // 完全背包,正向枚举
			{
				dp[j] = min(dp[j], dp[j - w[i]] + p[i]);
			}
		}
		if (dp[V] == INF) printf("This is impossible.\n");
		else printf("The minimum amount of money in the piggy-bank is %d.\n", dp[V]);
	}

	return 0;
}
posted @ 2019-03-31 22:36  CrossingOver  阅读(102)  评论(0编辑  收藏  举报