0-1揹包問題,hdu_2546_飯卡 問題

這道題不算難,即使是對於一個剛剛開始研究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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章