hdu 1114 Piggy-Bank

1.题目

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

2.分析

题目要求是装满,即在本价值限制LimitValue下减去本物品价值Value之后的LimitValue`必须存在一个已经计算出来的值。(如果采用初始化的值的话,就变成背包不要求装满,慢慢理解)。 因此,和完全背包的思路相似,则初始化的时候,要么初始化为整形最大值,计算的时候用state[i]=min(state[i],state[i-w]+p);要么初始化为整形最小值,计算的时候用判断state[i-w]是否不等于整形最小值(即是已经计算过值)。

动态规划方程:f[v]=max{f[v],f[v-cost]+weight}

3.复杂度

时间复杂度O(VN);空间复杂度O(V);

4.涉及内容

动态规划

5.感想

题目要求装满,因此是根据典型的完全背包变化而来。

关于背包初始化有两种情况:

1)背包不要求装满:初始化的时候,在任何一个价值限制下,0肯定都满足题目要求不装满,根据动态规划由前边导出后边值的时候0是一个满足条件的值。

2)背包要求装满:初始化的时候,在0价值限制下,0肯定满足要求装满;在非零价值线之下,由于是初始化,自然没有任何数值满足条件要求,因此可以初始化为整形最大值或者整形最小值,此时,在推导的时候都需要考虑上一次的价值是否是在装满条件下的(即不是整形最大值或者最小值,而是新计算出来的值)。判断的方法:当初始化为最小值的时候,用f[v]=max{f[v],f[v-cost]+weight};当初始化为最大值的时候,用f[v]=min{f[v],f[v-cost]+weight};或者用if判断f[v-cost]是否是初始化的值即可。

6.代码

#include <iostream>
using namespace std;
long state[10001];

void init()
{
	state[0]=0;
	for(int i=1;i<=10000;++i)
		state[i]=25000001;
}

long min(long a,long b)
{
	return a>b?b:a;
}

void CompletePack(int p,int w,int limitw)
{
	for(int i=w;i<=limitw;++i)
	{
		state[i]=min(state[i],state[i-w]+p);
	}
}

int main()
{
	freopen("in.txt","r",stdin);
	int T,E,F,N,P,W;
	cin>>T;
	while(T--)
	{
		init();
		cin>>E>>F>>N;
		while(N--)
		{
			cin>>P>>W;
			CompletePack(P,W,F-E);
		}
		if(state[F-E]!=25000001)
			cout<<"The minimum amount of money in the piggy-bank is "<<state[F-E]<<"."<<endl;
		else
			cout<<"This is impossible."<<endl;
	}
	return 0;
}

7.参考文献

《背包九讲》

你可能感兴趣的:(hdu 1114 Piggy-Bank)