还是基础的01背包,带了一点转换的思想、
由于题意要求的是只有饭卡金额大于等于5元,就可以买任何金额的菜、并且卡里面的金额可以为负数,求最少卡里会剩余多少钱。 由此我们可以按照dp的思想来求饭卡原本的余额m-5元 在n-1个道菜中,最多可以买的菜花掉的最大值,此时便剩余最后一道菜,也就是最贵的菜,并且我饭卡里的钱一定是大于等于5元的,所以我可以买最后一道菜、由此可知我们的答案便为m-dp[m-5]-w[n-1] ( m为饭卡里面初始的金额,dp[m-5]为我从n-1道菜里面买出我花费最大的金额的数量,w[n-1]为我最后购买了最贵的菜)、 还需要考虑的最后一个问题就是我饭卡里面的金额不是大于5的情况,不大于5的时候并不可以买任何一道菜,所以,直接输出便可、
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1100;
int n,m;
int w[maxn];
int dp[maxn];
int main()
{
while(scanf("%d",&n)&&n){
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
scanf("%d",&w[i]);
scanf("%d",&m);
sort(w,w+n);
for(int i=0;i<n-1;i++){
for(int j=m-5;j>=w[i];j--){
dp[j]=max(dp[j],dp[j-w[i]]+w[i]);
}
}
if(m<5)
printf("%d\n",m);
else
printf("%d\n",m-dp[m-5]-w[n-1]);
}
return 0;
}