1. 程式人生 > >hdu 2546 飯卡(貪心+01揹包)

hdu 2546 飯卡(貪心+01揹包)

飯卡

Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 14697 Accepted Submission(s): 5099
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沒想到還得用貪心,WA了好多次,還有,第二層for迴圈裡面不要寫成j〉=5。。。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX=10005;
int a[MAX];
int dp[MAX];
int main()
{
	int n;
	while(cin>>n,n)
	{
		for(int i = 1 ; i <= n; i ++){
			 cin>>a[i];
		}
        memset(dp,0,sizeof(dp));
        sort(a+1,a+n+1);
	    int m;
	    cin>>m;
	    if(m<5){
	    	cout<<m<<endl;
	    	continue;
	    }
	    m=m-5;
	    for(int i = 1; i < n; i++){
	    	for(int j = m; j >= a[i]; j--){
	    		   dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
	    	}
	    }
	    cout<<m-dp[m]-a[n]+5<<endl;
	}
	return 0;
}