题目链接:https://vjudge.net/contest/172125#problem/B
一道很常规的背包dp,不过要考虑几个细节:最后5块钱的话什么都可以买,所以最后五块钱肯定要买最大值的菜价,然后对于m-5的钱,就是裸背包问题了,直接上01背包模板就行。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=1005;
int dp[maxn][maxn];//前i个菜选j个的最大收益
int a[maxn];//菜价格
const int INF=0x3f3f3f3f;
int main()
{
int n,m;
while(scanf("%d",&n)!=EOF)
{
if(n==0)break;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
scanf("%d",&m);
if(m<5)
{
printf("%d\n",m);
continue;
}
for(int i=0;i<=m;i++)
{
dp[0][i]=0;
}
sort(a+1,a+n+1);
for(int i=1;i<n;i++)
{
for(int j=0;j<=m-5;j++)
{
dp[i][j]=dp[i-1][j];
if(j>=a[i])
dp[i][j]=max(dp[i][j],dp[i-1][j-a[i]]+a[i]);
}
}
printf("%d\n",m-dp[n-1][m-5]-a[n]);//留最后的五块钱买最大的
}
return 0;
}