連接:http://acm.hdu.edu.cn/showproblem.php?pid=2546php
#題目描述:c++
電子科大本部食堂的飯卡有一種很詭異的設計,即在購買以前判斷餘額。若是購買一個商品以前,卡上的剩餘金額大於或等於5元,就必定能夠購買成功(即便購買後卡上餘額爲負),不然沒法購買(即便金額足夠)。因此你們都但願儘可能使卡上的餘額最少。
某天,食堂中有n種菜出售,每種菜可購買一次。已知每種菜的價格以及卡上的餘額,問最少可以使卡上的餘額爲多少。ide
思路: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 }
。。blog
好久沒碰博客了,一直再說繼續打ACM,可是也只是口號喊得響。get
今天好不容易又開始作題博客
結果發現一道簡簡單單的01揹包問題居然有些作不來了
想要回到之前的水平
任重而道遠啊。
不過真好,最近仍是有個好朋友與我一塊兒在努力。