分析:要求余额最少,如果余额一开始就少于5元,直接输出。否则最后刷的那次肯定是要刷最贵的,所以只要求出除去最贵的价格,在m-5的钱中最多花多少。于是就转化为01背包问题,状态转移方程为:dp[j]=max{dp[j],dp[j-val[i]]+val[i]}.
# include <stdio.h>
# include <string.h>
int main()
{
int i,j,n,m,t,k,val[1005],dp[1005];
while(scanf("%d",&n),n!=0)
{
memset(dp,0,sizeof(dp));
for(i=1,k=0;i<=n;i++)
{
scanf("%d",&val[i]);
if(val[i]>val[k])
k=i;
}
scanf("%d",&m);
t=val[k];
val[k]=0;
for(i=1;i<=n;i++)
for(j=m-5;j>=val[i];j--)
if(dp[j-val[i]]+val[i]>dp[j])
dp[j]=dp[j-val[i]]+val[i];
if(m<5)
printf("%d\n",m);
else
printf("%d\n",m-dp[m-5]-t);
}
return 0;
}

1万+

被折叠的 条评论
为什么被折叠?



