[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揹包問題居然有些作不來了

想要回到之前的水平

任重而道遠啊。

不過真好,最近仍是有個好朋友與我一塊兒在努力。

相關文章
相關標籤/搜索