貪心法之最優裝載問題


概念:

當一個問題具有最優子結構性質時,可用動態規划算法,有時會有更簡單有效的算法,那就是貪心算法,貪心算法是通過一系列的選擇來得到問題的解,貪心算法並不從整體最優上加以考慮,所做的選擇只是在某種意義上的局部最優解。但對范圍相當廣的許多問題能產生整體最優解。在一些情況下,即使貪心算法不能得到整體最優解,但其最終結果卻是最優解的很好的近似解。

貪心算法的基本要素:

貪心選擇性質:所求解的問題的整體最優解可以通過一系列局部最優的選擇來,即貪心選擇達到。貪心選擇所依賴的是以前所做過的選擇,而對以后所做的選擇沒有關系。

最優子結構性質:一個問題的最優解包含其子問題的最優解。

貪心算法與動態規划的區別:

動態規划是通過自底向上的方式解決子問題,貪心算法是通過自頂向下的迭代方式做出貪心選擇,求解問題的最優解。兩共同點是都具有最優子結構性質


最優裝載問題:某艘船的載重量為C,每件物品的重量為wi,要將盡量多的物品裝入到船上。

分析:貪心策略:每次都選擇最輕的,然后再從剩下的n-1件物品中選擇最輕的。

算法策略:把n件物品 從小到大排序,然后根據貪心策略盡可能多的選出前i個物品,直到不能裝為止。

這個問題比部分背包問題還簡單,先拿輕的再拿重的可以保證最后物品裝的最多。代碼如下:

#include<iostream>
#include<algorithm>
#define MAXN 10000
using namespace std;
int main(){
    int c,n;    //c:船的最高載重量 n:古董數量
    int sum=0,weight=0; //sum:裝入的古董數量 weight:裝入的古董重量
    int w[MAXN];    //單個古董對應的重量
    cout<<"請輸入最高載重量和需載的古董數目:"<<endl;
    cin>>c>>n;
    cout<<"請分別輸入這些古董的重量:"<<endl;
    for(int i=1;i<=n;++i)
        cin>>w[i];
    sort(w+1,w+1+n);
    for(int i = 1 ; i<=n ; i++){
        weight += w[i]; //先將重量加進去
        if(weight >= c){
            if(weight == c)   //恰好裝滿時
                sum = i;
            else
                sum = i-1;  //超重了,需要減去一個
            break;
        }
    }
    cout<<"最多可以裝"<<sum<<""<<endl;
    for(int i=1;i<=sum;++i)
        cout<<w[i]<<" ";
    return 0;
}
View Code

程序運行結果:

 參考:王曉東《算法設計與分析》

            https://blog.csdn.net/qq648483997/article/details/93309028


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM