[HDU2546]饭卡

   连接:http://acm.hdu.edu.cn/showproblem.php?pid=2546php

#题目描述:c++

电子科大本部食堂的饭卡有一种很诡异的设计,即在购买以前判断余额。若是购买一个商品以前,卡上的剩余金额大于或等于5元,就必定能够购买成功(即便购买后卡上余额为负),不然没法购买(即便金额足够)。因此你们都但愿尽可能使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可以使卡上的余额为多少。ide

#输入
多组数据。对于每组数据:
第一行为正整数n,表示菜的数量。n<=1000。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m,表示卡上的余额。m<=1000。
n=0表示数据结束。
#输出
对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。
#样例输入
1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0
#样例输出
-45
32

 思路:spa

典型的01背包类问题,将余额减去5,就是背包的容量,而后尽量多的往里面装东西。由于能够负的,因此减去的5最后能够买下最贵的菜。设计

题就变成了,去除价格最高后剩下的物品,余额减去5的背包容量,使背包最后剩下的容量最小。rest

得出的这个结果加上5再减去最贵的菜就是答案。code

 

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define inf 0x3fffffff
 4 using namespace std;
 5 
 6 int read(){
 7     int x=0,f=1;char ch=getchar();
 8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
10     return x*f;
11 }
12 
13 void fre(){
14      freopen("     .in","r",stdin);
15      freopen("     .out","w",stdout);
16 }
17 
18 int n,val[1005],rest,dp[1005];
19 
20 void sce_main(){
21     for(int i=1;i<=n;i++){
22         val[i]=read();
23     }rest=read();
24     sort(val+1,val+1+n);
25     if(rest<5){
26         cout<<rest<<endl;return ;
27     }
28     rest-=5;
29     memset(dp,0,sizeof(dp));
30     for(int i=1;i<=n-1;i++){
31         for(int j=rest;j>=val[i];j--){
32             dp[j]=max(dp[j],dp[j-val[i]]+val[i]);
33         }
34     }
35     cout<<rest-dp[rest]+5-val[n]<<endl;
36 }
37 
38 int main(){
39     while(scanf("%d",&n)!=EOF){
40         if(n==0)return 0;
41         sce_main();        
42     }
43     return 0;
44 }
View Code

。。blog

好久没碰博客了,一直再说继续打ACM,可是也只是口号喊得响。get

今天好不容易又开始作题博客

结果发现一道简简单单的01背包问题居然有些作不来了

想要回到之前的水平

任重而道远啊。

不过真好,最近仍是有个好朋友与我一块儿在努力。

相关文章
相关标签/搜索