這道題不算難,即使是對於一個剛剛開始研究acm的人來說仔細分析後也能有所想法。本人剛剛開始acm之路不久,通過查資料,知道這是一道揹包問題,而且是最簡單的0-1揹包問題,資料來源於WIKI百科http://zh.wikipedia.org/zh-cn/%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98。
這道題的思路是:首先,當錢m<5的時候,肯定買不了東西,當m=5的時候,肯定是m-pr(最貴)。(pr是菜的價格)。
其次,想一下,怎麼才能讓剩的錢最最少呢?如果是用m減去最貴的再減去次貴的,那麼當m<5的時候輸出????這是不對的!!正確的想法是:將你的錢m減去菜的價格一直減到m最接近5,然後用這個最接近5的m減去最貴的。————所以,將m-5當作是揹包的最大容量,將最貴的菜拿出來(最後還得用它呢),剩下菜的價格就是往裏邊塞得東西。最後輸出m-dp[m-5]-pr(最貴)!!
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <memory.h>
#define max(a,b) ((a)>=(b)?(a):(b))
using namespace std;
int N;
int m;
int dp[50000];
int main()
{
while(scanf("%d",&N)!=EOF&&N!=0){
int pr[1100];
for(int i=0;i<N;i++){
scanf("%d",&pr[i]);
}
sort(pr,pr+N);
scanf("%d",&m);
if(m<5) printf("%d\n",m);
else if(m==5) printf("%d\n",m-pr[N-1]);
else{
memset(dp,0,sizeof(dp));
for(int i=0;i<N-1;i++){
for(int j=m-5;j>=pr[i];j--){
dp[j]=max(dp[j],dp[j-pr[i]]+pr[i]);
}
}
printf("%d\n",m-dp[m-5]-pr[N-1]);
}
}
return 0;
}