饭卡余额大于等于5都可以买,给出饭卡买各种菜后使余额最小(可为负)
最优法:先挑出最大的,饭卡金额减5再背包剩下的,再减掉最大的。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX_N = 1000, MAX_W = 1000;
int n, W;
int c[MAX_N];
int dp[MAX_W + 1];
void solve()
{
for(int i = 0; i < n; i++)
for(int j = W - 5; j >= c[i]; j--)
{
if(dp[j] < dp[j - c[i]] + c[i])
dp[j] = dp[j - c[i]] + c[i];
}
}
int main()
{
while(scanf("%d",&n))
{
if(n == 0)
return 0;
else
{
int temp = 0,temp1;
for(int i = 0; i < n; i++)
{
scanf("%d", &c[i]);
if(c[i] > temp)
{
temp = c[i];
temp1 = i;
}
}
c[temp1] = 0; // 挑出最大保存后变为0,防止背包时背到。
scanf("%d", &W);
if(W < 5)
{
printf("%d\n", W);
continue;
}
memset(dp,0,sizeof(dp));
solve();
printf("%d\n",W - dp[W - 5] - temp);
}
}
}