hduoj 2546 飯卡(揹包)

飯卡

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 23303    Accepted Submission(s): 8193


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


題目地址:hduoj 2546

思路:1:這一題的揹包有所不同,因爲飯卡里的錢可以是負數,前提是刷卡前m>=5,求的是最低飯卡里可以減爲多少錢,

     2:可以先sort排序(由小到大),第二步把n-1樣菜買了,最後買最貴的第n樣菜,此時使得飯卡里的錢最低,低到負數。

     3:額外注意,以前的核心語句是f[j] = max(f[j], f[j-cost[i]]+val[i]);

       現在是 f[j] = max(f[j], f[j-a[i]]+a[i]);


AC代碼:

#include<cstdio>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
	int n, m, a[1005], f[1005];
	while(scanf("%d", &n), n)
	{
		int i, j, exp=0;
		for(i = 0; i < n; i++)
			scanf("%d", &a[i]);
		sort(a, a+n);
		exp = a[n-1];	  
	    scanf("%d", &m);
	    if(m < 5)
	    {  printf("%d\n", m);  continue;  }
		memset(f, 0, sizeof(f));
	    for(i = 0; i < n-1; i++)
	    {
	    	for(j = m-5; j >= a[i]; j--)
	    	{
	    		f[j] = max(f[j], f[j-a[i]]+a[i]);
			}
		}
	    printf("%d\n", m-exp-f[m-5]);   
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章