hdu2546 饭卡 01-背包问题

转载请注明出处:http://blog.csdn.net/u012860063

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546

Problem Description

电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。

某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。

Input

多组数据。对于每组数据:

第一行为正整数n,表示菜的数量。n<=1000。

第二行包括n个正整数,表示每种菜的价格。价格不超过50。

第三行包括一个正整数m,表示卡上的余额。m<=1000。

n=0表示数据结束。

Output

对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。

Sample Input

1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0

Sample Output

-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;
}

hdu2546 饭卡 01-背包问题,布布扣,bubuko.com

时间: 2024-08-13 17:30:48

hdu2546 饭卡 01-背包问题的相关文章

HDU 2546 饭卡 01背包问题

01背包问题,增加一个额外条件,余额大于等于5的时候,可以购买任意价格的东西,那么就把5保留下来买最大价格的物品. 然后转化为收益的时候要注意初始条件,即没买东西的时候收益就是余额,就是所有的钱.这个还是有点难转换思维的. 最后是要熟悉背包填表,不需要保留选择的时候,就逆向填表,只需要一维表就可以了,当然也可以使用滚动数组,两个一维数组就可以了. 走了算法一圈回来了,AC自动机,线段树等都学会了,但是遇上这些基础DP还是不太轻松,看来需要继续打打基础.主要是思维转换不够流畅,速度就不快了. #i

HDU2546饭卡(变形01背包)

饭卡 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11354    Accepted Submission(s): 3904 Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无

UESTC 31 饭卡(Card) --背包问题

背包问题. 思路:如果m<5,此时也不能消费,所以此时答案为m m>=5: 求出背包容量为m-5,买前n-1样便宜的菜(排个序)的最大价值(即最大消费,即消费完后剩余值最接近5)最后减去最大的那个菜的价格,就得到最小的余额. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using n

HDU2546:饭卡(01背包)

HDU2546:饭卡 http://acm.hdu.edu.cn/showproblem.php?pid=2546 当我们遇到问题选择物体的价值和顺序相关时就需要,排完序后对其01处理.这题因为当我们小的先点的话则越接近5,然后我们一次取最大值,则我们花的钱就越多. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string>

hdu2546 饭卡 (背包问题)

饭卡 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16416    Accepted Submission(s): 5708 Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无

HDU-2546 饭卡 ( DP )

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2546 Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够).所以大家都希望尽量使卡上的余额最少.某天,食堂中有n种菜出售,每种菜可购买一次.已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少. Input 多组数据

hdu2546 饭卡

Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够).所以大家都希望尽量使卡上的余额最少. 某天,食堂中有n种菜出售,每种菜可购买一次.已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少. Input 多组数据.对于每组数据: 第一行为正整数n,表示菜的数量.n<=1000. 第二行包括n个正整数,表示每种菜的价

hdu 2546 饭卡(0-1背包)

题目来源:hdu 2546 饭卡 饭卡 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16645 Accepted Submission(s): 5797 Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后

hdu 2546 饭卡(01背包)

Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够).所以大家都希望尽量使卡上的余额最少. 某天,食堂中有n种菜出售,每种菜可购买一次.已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少. Input 多组数据.对于每组数据: 第一行为正整数n,表示菜的数量.n<=1000. 第二行包括n个正整数,表示每种菜的价