動態規划之背包問題


【原創】

在動態規划中有一個經典的問題,背包問題,一個背包體積為V,現有n件物品,每件物品都有其價值w和體積v,現在要求將物品裝入背包,要求使其獲得的價值最大,對這個問題,我們引入一個概念“性價比”,即價值和體積的比值w/v,表明單位體積的價值量,那么自然而然我們在選擇物品時,一定是以此選擇”性價比“大的物品,所以在數據處理時必須將物品按照“性價比”按照遞減排序;下面來看一個題目描述

題目描述:
辰辰是個很有潛能、天資聰穎的孩子,他的夢想是稱為世界上最偉大的醫師。
為此,他想拜附近最有威望的醫師為師。醫師為了判斷他的資質,給他出了一個難題。
醫師把他帶到個到處都是草葯的山洞里對他說:
“孩子,這個山洞里有一些不同的草葯,采每一株都需要一些時間,每一株也有它自身的價值。
我會給你一段時間,在這段時間里,你可以采到一些草葯。如果你是一個聰明的孩子,你應該可以讓采到的草葯的總價值最大。”
如果你是辰辰,你能完成這個任務嗎?
輸入:
輸入的第一行有兩個整數T(1 <= T <= 1000)和M(1 <= M <= 100),T代表總共能夠用來采葯的時間,M代表山洞里的草葯的數目。
接下來的M行每行包括兩個在1到100之間(包括1和100)的的整數,分別表示采摘某株草葯的時間和這株草葯的價值。
輸出:
可能有多組測試數據,對於每組數據,
輸出只包括一行,這一行只包含一個整數,表示在規定的時間內,可以采到的草葯的最大總價值。 
樣例輸入:
70 3
71 100
69 1
1 2

這里是采葯問題,但是對比背包,這個問題是一樣的變形,沒有什么特殊之處,我們來看看代碼:

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
//0-1背包問題
struct bag{
    int t;
    int v;
    double w;
    void set_w(){
        w = (double)v/t;
    }
    bool operator < (const bag &A) const{//重載小於符號,使其能夠排序;
        return w > A.w;
    }
}bag_list[101];
 
void test_2() {
    int t,m;
    while( scanf("%d%d",&t,&m)!=EOF){
    for (int i = 1; i<=m; i++) {
        scanf("%d%d",&bag_list[i].t,&bag_list[i].v);
        bag_list[i].set_w();
    }
//        for (int i = 1; i<=m; i++) {
//            printf("%d %d %0.2f\n",bag_list[i].t,bag_list[i].v,bag_list[i].w);
//        }
    sort(bag_list+1, bag_list+m+1);//這個地方是m+1哦,如果下標是0開始,則是m
//        for (int i = 1; i<=m; i++) {
//            printf("%d %d %0.2f\n",bag_list[i].t,bag_list[i].v,bag_list[i].w);
//        }
    int ans = 0;
    for (int i =1; i<=m; i++) {
        if(bag_list[i].t<=t){
            ans+=bag_list[i].v;
            t -= bag_list[i].t;
        }
    }
    printf("%d\n",ans);
    }
}
 
int main() {
//    test_1();
    test_2();
    return 0;
}
 

這里使用了庫函數,以及結構體中定義函數以及重載操作符的使用,sort是c++函數庫中的函數,這個方法很方便,他對bag_list進行排序,之所以能夠進行主要是因為bag中對<進行了重載,所以能夠自動排序,如果沒有重載,這里排序是有錯誤的;


免責聲明!

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



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