饭卡(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 }

 

 

 

 

 

-

posted @ 2020-01-20 11:04  jiamian22  阅读(419)  评论(0编辑  收藏  举报