转载请注明出处:http://blog.csdn.net/u012860063
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546
价格不超过50。
第三行包含一个正整数m,表示卡上的剩余金额。
m<=1000。
n=0表示数据结束。
1 50 5 10 1 2 3 2 1 1 2 3 2 1 50 0
-45 32
思路:
先把最贵的一种菜找到放在一边,用剩余金额减5的金钱去尽可能买 除掉最贵的菜后剩余的菜类(01-背包问题)!
最后再用余下的钱去买最贵的菜。
代码例如以下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define M 50047
int f[M],val[M];
int max(int a,int b)
{
	if(a > b)
		return a;
	else 
		return b;
}
int main()
{
	int n,m,i,j;
	while(~scanf("%d",&n) && n)
	{
		memset(f,0,sizeof(f));
		memset(val,0,sizeof(val));
		for(i = 0 ; i < n ; i++)
		{
			scanf("%d",&val[i]);
		}
		sort(val,val+n);//排序后val[n-1]即为最贵的菜
		scanf("%d",&m);
		if(m < 5)
		{
			printf("%d\n",m);
			continue;
		}
		for(i = 0 ; i < n-1 ; i++)//01-背包问题
		{
			for(j = m-5 ; j >= val[i]; j--)
			{
				f[j] = max(f[j],f[j-val[i]]+val[i]);
			}
		}
		printf("%d\n",m-f[m-5]-val[n-1]);
	}
	return 0;
}
原文:http://www.cnblogs.com/liguangsunls/p/6914542.html