POJ 1384 Piggy-Bank

本文深入讲解了完全背包问题中的初始化及解决策略,并提供了一个具体的代码示例,帮助读者理解如何求解最小价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

完全背包的装满问题

凡是求装满或不装满,都是由于初始化决定的。
一定要记住,DP的初始化是满足解的条件(或待定解状态)

而对于完全背包:
dp[i][j]dp[i][j]dp[i][j] 表示 前 iii 件物品在拥有最大体积 jjj 的情况下,所得到的最大价值。

dp[0][j](j=0......V)dp[0][j] (j=0......V)dp[0][j]j=0......V 时,表示的是前 000 个物品最大价值,那么肯定是没有装东西的,所以这一行(对于二维)全部初始化为 000

dp[i][0](i=0.....N)dp[i][0] (i=0.....N)dp[i][0](i=0.....N) 时,表示的是前 iii 件商品,背包所能承受的最大体积是 000 的时候的最大价值,那都装不了东西了(题目有说花费大于 000 的话),值肯定也是 000 了。
注意一点的是,在有些题中,物品的花费可能可以是 000 ,那么我初始化的时候应该是物品的价值,而并非赋值 dp[i][0]dp[i][0]dp[i][0]000

那么对于以上这些边界之外的情况,初始化为 无穷即可(求最大值时,初始化为负无穷。最小值时,初始化为 正无穷 。)
解释:如果求的是最小值,那么不是边界情况的话,我一开始的时候并不知道会放哪些东西进去,所以一切都是待定、未知的状态待定、未知的状态,而由于求的是最小值,所以我们初始化为最大值的话,即能让数组里面的值为待定状态,又能让当接收一个值时,它可以作为比无穷大更小的值,加入数组当中。

上面说的是二维,空间优化后的一维见代码即可。

代码如下:

#include<iostream>
#include<algorithm>
#include<string.h>
#define inf 0x3f3f3f3f
using namespace std;
int T;
int e, f, n, v;
int dp[10008];
struct Node
{
	int w;
	int val;
}A[508];
void init()
{
	memset(dp, 0x3f, sizeof(dp));
	dp[0] = 0;
	return;
}
int main()
{
	scanf("%d", &T);
	while (T--)
	{
		init();
		scanf("%d%d", &e, &f);
		v = f - e;
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) {
			scanf("%d%d", &A[i].val, &A[i].w);
		}
		for (int i = 1; i <= n; i++) {
			for (int j = A[i].w; j <= v; j++) {
				dp[j] = min(dp[j], dp[j - A[i].w] + A[i].val);
			}
		}
		if (dp[v] != inf)
			printf("The minimum amount of money in the piggy-bank is %d.\n", dp[v]);
		else
			printf("This is impossible.\n");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值