此题要求余额大于5时可以买任意价值的东西。所以我们把给定的余额w先减去5,在进行01背包。
对饭菜的价值排序,是为了当余额大于等于5时,在去买最大价值的东西。
dp[i] 代表余额为i时,可以买的最大价值。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int dp[50010];
int s[50010];
int main()
{
int i,j,n,w;
while(scanf("%d",&n)&&n)
{
for(i=1;i<=n;i++)
{
scanf("%d",&s[i]);
}
memset(dp,0,sizeof(dp));
scanf("%d",&w);
if(w<5)
{
printf("%d\n",w);
continue;
}
sort(s+1,s+1+n);
int sum=w;
w-=5;
for(i=1;i<n;i++)
for(j=w;j>=s[i];j--)
{
dp[j]=max(dp[j],dp[j-s[i]]+s[i]);
}
printf("%d\n",sum-dp[w]-s[n]);
}
return 0;
}