A - 小彭玉的扫荡食堂计划
Time Limit: 20000/10000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
Problem Description
哗啦啦村的食堂很奇怪,就是如果这个饭卡所剩金额低于5元的话,这个饭卡就不能刷了。
也就是说,只要这个饭卡金额大于等于5元,就可以随便刷~
有一天,小彭玉看了看哗啦啦食堂的饭,“哇,好好吃!我要全部都买下来!”
但是小彭玉并没有那么多钱,于是他准备充分利用自己的钱,去买这些食物!
请问最后小彭玉的饭卡余额最少能到多少?
Input
多组测试数据(最多100组)
第一行 n,表示有n个菜
第二行 接下来n个数字,a[i]表示第i道菜多少钱
第三行 一个数m,表示小彭玉的饭卡,一开始有m元
1<=n<=1000,1<=a[i]<=10000,1<=m<=10000
Output
输出一个整数,表示最后饭卡显示的金额数
Sample Input
1 10000 6 10 1 2 3 2 1 1 2 3 2 1 50
Sample Output
-9994 32
解法:01背包的使用,因为5块钱可以买任何东西,所以,我们把价格最贵的菜独自拿出来,我们只需要用(N-1)份菜去查找价钱容量为(M-5),所能够买到的最大值。最后在减去价格最大的那份菜的价格即可。
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 #define MAX 10100 7 int DP[MAX]; 8 int val[MAX]; 9 int main() 10 { 11 int N,M,i,j,Max; 12 while(scanf("%d",&N)!=EOF) 13 { 14 for(i=0,Max=0;i<N;i++) 15 { 16 scanf("%d",&val[i]); 17 if(val[i]>Max)Max=val[i];/*取最大值*/ 18 } 19 scanf("%d",&M); 20 for(i=0;i<=M;i++)DP[i]=0; 21 if(M<5||N==0){printf("%d ",M);continue;} 22 else 23 { 24 int sign=1; 25 for(i=0;i<N;i++) 26 { 27 if(sign&&val[i]==Max)/*去除一次最大值*/ 28 {sign=0;continue;} 29 for(j=M-5;j>=val[i];j--) 30 { 31 if(DP[j]<DP[j-val[i]]+val[i]) 32 { 33 DP[j]=DP[j-val[i]]+val[i]; 34 } 35 } 36 } 37 printf("%d ",M-DP[M-5]-Max); 38 } 39 } 40 return 0; 41 }