飯卡
某天,食堂中有n種菜出售,每種菜可購買一次。已知每種菜的價格以及卡上的餘額,問最少可使卡上的餘額爲多少。
第一行爲正整數n,表示菜的數量。n<=1000。
第二行包括n個正整數,表示每種菜的價格。價格不超過50。
第三行包括一個正整數m,表示卡上的餘額。m<=1000。
n=0表示數據結束。
題目地址: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;
}