饭卡(DP)
电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。
如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
输入格式
第一行为正整数n(n≤1000),表示菜的数量。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m(m≤1000),表示卡上的余额。
输出格式
对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。
样例输入1
1 50 5
样例输出1
-45
样例输入2
10 1 2 3 2 1 1 2 3 2 1 50
样例输出2
32
01背包+贪心
本题是对背包的巧妙应用,只有理解了背包才能轻松的做出这道题目。
排序后,把前n-1个物品计算01背包,计算出背包最大可以装多少价值的物品。
最后加上最大的物品的价值就可以了。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <sstream> 13 #include <ctime> 14 const int INF=0x3f3f3f3f; 15 typedef long long LL; 16 const int mod=1e9+7; 17 const LL MOD=1e9+7; 18 const double PI = acos(-1); 19 const double eps =1e-8; 20 #define Bug cout<<"---------------------"<<endl 21 const int maxn=1e5+10; 22 using namespace std; 23 24 int a[1005]; 25 int dp[1005]; 26 27 int main() 28 { 29 #ifdef DEBUG 30 freopen("sample.txt","r",stdin); 31 #endif 32 // ios_base::sync_with_stdio(false); 33 // cin.tie(NULL); 34 35 int n,m; 36 scanf("%d",&n); 37 for(int i=1;i<=n;i++) 38 scanf("%d",&a[i]); 39 scanf("%d",&m); 40 dp[0]=1; 41 sort(a+1,a+1+n); 42 int MAX=0; 43 for(int i=1;i<=n;i++) 44 { 45 for(int j=m-5;j>=0;j--) 46 { 47 if(dp[j]) 48 { 49 dp[j+a[i]]=1; 50 MAX=max(MAX,j+a[i]); 51 } 52 } 53 } 54 printf("%d\n",m-MAX); 55 56 return 0; 57 }
-