http://acm.hdu.edu.cn/showproblem.php?pid=2546
題意:
電子科大本部食堂的飯卡有一種很詭異的設計,即在購買之前判斷余額。如果購買一個商品之前,卡上的剩余金額大於或等於5元,就一定可以購買成功(即使購買后卡上余額為負),否則無法購買(即使金額足夠)。所以大家都希望盡量使卡上的余額最少。
某天,食堂中有n種菜出售,每種菜可購買一次。已知每種菜的價格以及卡上的余額,問最少可使卡上的余額為多少。
思路:我們先用一個背包容量為price-5的背包去裝菜,背包里東西裝得越多,余額則越少。在背包裝滿之后,飯卡里的余額肯定是大於等於5的,根據題意可以知道只要飯卡大於等於5元,我們就可以買任何的菜,所以最后我們可以再減去一個最貴的菜,這樣飯卡的余額就可以最少了。當然,所有的前提需要將菜的價格排序。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 6 const int maxn = 1000+5; 7 8 int n; 9 int dp[maxn]; 10 int price; 11 12 int w[maxn]; 13 14 int main() 15 { 16 //freopen("D:\\txt.txt", "r", stdin); 17 while (cin >> n && n) 18 { 19 memset(dp, 0, sizeof(dp)); 20 for (int i = 1; i <= n; i++) 21 cin >> w[i]; 22 sort(w + 1, w + 1 + n); 23 cin >> price; 24 if (price >= 5) 25 { 26 for (int i = 1; i <= n - 1; i++) 27 { 28 for (int j = price - 5; j >= w[i]; j--) 29 dp[j] = max(dp[j], dp[j - w[i]] + w[i]); 30 } 31 cout << price - dp[price - 5] - w[n] << endl; 32 } 33 else cout << price << endl; 34 } 35 return 0; 36 }