hdu 2546 饭卡 (01背包)

点击打开链接

题目是01背包的变形。刚开始没看出来。Wrong了好几次!!

当卡上金额大于等于5元时才能购买成功,我们不妨将这里的5元视为“0“,因为在DP过程中金额不能低于5,所以最后要用到的结果应该是dp[m-5]。既然我们保证了余额一直是大于等于5的,那么最后还能购买一次,所以,我们将最贵的一样菜留在最后,在DP的过程结束之后再购买,这样就能保证最后的余额最少。

这样也是可以的,只是要注意最后结果应该使用dp[m],而不是dp[m+5],开始由于使用了dp[m+5],所以WA了。j从m+5到5,也是为了保证不小于5元,但是实际上m to 5就行了。

#include"stdio.h"
#include"string.h"
int dp[1001];
int MAX(int x,int y)
{
	return x>y?x:y;
}
int main()
{
	int n,m,a[1001],i,j,max,jj;
	while(scanf("%d",&n)!=-1&&n)
	{
		max=0;
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
			if(max<a[i])
			{
				max=a[i];jj=i;
			}
		}
		scanf("%d",&m);
		if(m<5)
			printf("%d\n",m);
		else
		{
			memset(dp,0,sizeof(dp));
			for(i=0;i<n;i++)
			{
				for(j=m+5;j>=5;j--)
					if(j-a[i]>=5&&i!=jj)
						dp[j]=MAX(dp[j],dp[j-a[i]]+a[i]);
			}
			printf("%d\n",m-dp[m]-a[jj]);
		}
	}
	return 0;
}


posted on 2012-11-01 16:14  Slege  阅读(116)  评论(0编辑  收藏  举报

导航