HDU2546:飯卡(01揹包)

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
 


 再重新做一次揹包題目吧!

這題留意兩點

①給出的m小於5時,無法購買

給出的m大於5時,儘可能令消耗飯卡里的錢,使剩下的錢儘量接近5元,然後買最貴的東西,那就可以有最小余額。因此問題就轉化成:給你m-5元在題目的要求的條件中購買,使錢儘量接近5元且價格最大。01揹包無誤,這裏的揹包體積m 和 物品的價值和代價都是蔬菜價格


#include<stdio.h>
#include<algorithm>
using namespace std;
int dp[1010], a[1010];

int main()
{
	int n, w;
	while (scanf("%d", &n), n)
	{
		memset(dp, 0, sizeof(dp));
		for (int i = 1; i <= n; i++)
			scanf("%d", a + i);
		scanf("%d", &w);
		if (w < 5)
		{
			printf("%d\n", w); continue;
		}
		sort(a + 1, a + 1 + n);
		int MAX = a[n];
		w -= 5;
		for (int i = 1; i < n; i++)
		{
			for (int j = w; j >= a[i]; j--)
					dp[j] = max(dp[j],dp[j - a[i]] + a[i]);
		}
		printf("%d\n", w + 5 - MAX - dp[w]);
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章