【原創】
在動態規划中有一個經典的問題,背包問題,一個背包體積為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中對<進行了重載,所以能夠自動排序,如果沒有重載,這里排序是有錯誤的;