HDU-1114(完全背包)

题目:acm.hdu.edu.cn/showproblem.php?pid=1114

    这个题的关键在于“背包”是恰好完全装满的,所以涉及到一个小技巧:初始化将dp[1...v]设为负无穷,dp[0]设为0,最后dp[v]即所求。

好吧,其实这个技巧在我看《背包九讲》的时候已经看见了_(:з」∠)_,但是操作起来还是有点困难。

首先,这个题要求的是背包恰好完全装满时做少的钱,(o(╥﹏╥)o一般背包问题都求最大的“价值”,所以用到无穷小)所以要设为无穷大啊!!!

总结:

求最大值,dp数组除dp[0]=0外初始化为无穷小 #define Min 0xc0c0c0c0 最后特判if (dp[v]>0)

求最小值,dp数组除dp[0]=0外初始化为无穷大 #define Max 0x3f3f3f3f  最后特判if (dp[v]!=Max)

PS:此时初始化不能用memset (dp,Min,sizeof(dp)) !!!因为memset初始化只对0,-1有用

(不知道为啥在网上看了那么多不是0,-1也用memset初始化的_(:з」∠)_,反正我dev编译有问题→_→)

如果runtime error,再看一遍题,是不是数组开小了

(这道题我一开始没想清楚,dp[505]结果wa了好久看不出来o(╥﹏╥)o,蠢爆了ヾ( ̄▽ ̄)Bye~Bye~)

代码:

#include <bits/stdc++.h>
using namespace std;
#define Max 0x3f3f3f3f //无穷大 
int main()
{
	int t,n;
	int p[505],w[505]; //price,weight
	int dp[10005]; //钱罐中的钱 
	cin>>t;
	while (t--)
	{
		
		int before,after,v;
		cin>>before>>after;
		v=after-before;
		cin>>n;
		for (int i=0;i<10005;i++)
		{
			dp[i]=Max;
		}
		dp[0]=0;
		for (int i=1;i<=n;i++)
		{
			cin>>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]!=Max) cout<<"The minimum amount of money in the piggy-bank is "<<dp[v]<<"."<<endl;
		else cout<<"This is impossible."<<endl;
		
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40865837/article/details/81155965