1. 程式人生 > >[VJ][簡單背包]杭電飯卡

[VJ][簡單背包]杭電飯卡

mes 基礎上 string -a 都是 isp max hide 分享

飯卡

Description

電子科大本部食堂的飯卡有一種很詭異的設計,即在購買之前判斷余額。如果購買一個商品之前,卡上的剩余金額大於或等於5元,就一定可以購買成功(即使購買後卡上余額為負),否則無法購買(即使金額足夠)。所以大家都希望盡量使卡上的余額最少。
某天,食堂中有n種菜出售,每種菜可購買一次。已知每種菜的價格以及卡上的余額,問最少可使卡上的余額為多少。

Input

多組數據。對於每組數據:
第一行為正整數n,表示菜的數量。n<=1000。
第二行包括n個正整數,表示每種菜的價格。價格不超過50。
第三行包括一個正整數m,表示卡上的余額。m<=1000。

n=0表示數據結束。

Output

對於每組輸入,輸出一行,包含一個整數,表示卡上可能的最小余額。

Examples

Input

1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0

Output

-45
32

正確解法:

自己瞎造出來的算法錯了qaq,應該先把 5這個數減下去,就可以轉化為 有m個錢,買東西最多能買多少金額的?

因為前期減去了5嘛,所以要特殊一下,如果m直接就<0,就直接輸出m,當m>=5時,才有了下面的東西。

由背包問題很容易得出 f[m]=max( f[m], f[m-a[i]]+a[i]);  0<i<n ;

然後就是總共的錢減去算出的 f[m] ,再減去a[i]中最大的那個數!

因為前面所算的所有都是在m-5的基礎上,m-5是永遠大於0的,減去最大的那個,使金額小於0。才是最後得出的答案啊!

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 using namespace std;
 8 int n,m;
 9 int f[1010], a[1010] = {0};
10 int main()
11 {
12 while (cin >> n) 13 { 14 if (n == 0) break; 15 memset(a, 0, sizeof(a)); 16 memset(f, 0, sizeof(f)); 17 for (int i = 0; i < n; i++) 18 cin >> a[i]; 19 cin >> m; 20 m = m - 5; 21 if (m >= 0) 22 { 23 sort(a, a + n); 24 for (int i = 0; i < n - 1; i++) 25 for (int j = m; j >= a[i]; j--) 26 f[j] = max(f[j], f[j - a[i]] + a[i]); 27 cout << m + 5 - f[m] - a[n - 1] << endl; 28 } 29 else 30 cout << m + 5 << endl; 31 } 32 return 0; 33 }
View Code

[VJ][簡單背包]杭電飯卡