题目就是尽量把饭卡钱用完,如果饭卡钱少于5元就不能买了。
我们可以先留5块钱,用剩下的钱尽量多买(0-1背包问题,求最大容量),然后用那剩下的五块钱去买前面没有买过最贵的东西,这样就是花的最多,卡余额最少的
注意开始的时候如果就少于五块钱,那就什么也买不了了
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int dp[1010][1010],val[1010],mark[1010];
int Max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int n,maxv,ans;
int i,j,m,t;
while(scanf("%d",&n)!=EOF && n!=0)
{
memset(val,0,sizeof(val));
memset(mark,0,sizeof(mark));
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
{
scanf("%d",&val[i]);
}
sort(val,val+n);
scanf("%d",&m);
if(m<5)
{
printf("%d\n",m);
continue;
}
for(i=0;i<n;i++)
{
for(j=0;j<=m-5;j++)
{
if(j>=val[i])
{
dp[i+1][j]=Max(dp[i][j-val[i]]+val[i],dp[i][j]);
}
else
dp[i+1][j]=dp[i][j];
}
}
j=m-5;
for(i=n;i>=1;i--)
{
if(dp[i][j]>dp[i-1][j])
{
mark[i-1]=1;
j=j-val[i-1];
}
}
t=0;
for(i=n-1;i>=0;i--)
if(mark[i]==0) break;
if(i>=0) t=val[i];
ans=m-dp[n][m-5]-t;
printf("%d\n",ans);
}
return 0;
}