NOIP2005 普及組複賽 第三題 採藥

2022-05-13 04:33:28 字數 4627 閱讀 6792

題目描述description

辰辰是個天資聰穎的孩子,他的夢想是成為世界上最偉大的醫師。為此,他想拜附近最有威望的醫師為師。醫師為了判斷他的資質,給他出了乙個難題。醫師把他帶到乙個到處都是草藥的山洞裡對他說:「孩子,這個山洞裡有一些不同的草藥,採每一株都需要一些時間,每一株也有它自身的價值。我會給你一段時間,在這段時間裡,你可以採到一些草藥。如果你是乙個聰明的孩子,你應該可以讓採到的草藥的總價值最大。」 

如果你是辰辰,你能完成這個任務嗎?

輸入輸出格式input/output

輸入格式:

輸入檔案medic.in的第一行有兩個整數t(1 <= t <= 1000)和m(1 <= m <= 100),用乙個空格隔開,t代表總共能夠用來採藥的時間,m代表山洞裡的草藥的數目。接下來的m行每行包括兩個在1到100之間(包括1和100)的整數,分別表示採摘某株草藥的時間和這株草藥的價值。

輸出格式:

輸出檔案medic.out包括一行,這一行只包含乙個整數,表示在規定的時間內,可以採到的草藥的最大總價值。

輸入輸出樣例sample input/output

樣例測試點#1

輸入樣例:

70 3

71 100

69 1

1 2輸出樣例:

3

說明description

對於30%的資料,m <= 10;

對於全部的資料,m <= 100。

noip2005普及組第三題

思路:這題要用到貪心演算法(動態規劃),在最少的藥內求得最大的價值(和01揹包問題一樣),可以把總共採藥時間看作是體積,每乙個藥是物品。

既然說到了著名的揹包問題,那麼就來詳解一下這題吧!

對於這個問題,一開始確實有點不太好入手。一堆的物品,每乙個都有一定的質量和價值,我們能夠裝入的總重量有限制,該怎麼來裝使得價值最大呢?對於這n個物品,每個物品我們可能會選,也可能不選,那麼我們總共就可能有2^n種組合選擇方式。如果我們採用這種辦法來硬算的話,則整體的時間複雜度就達到指數級別的,肯定不可行。

現在我們換一種思路。既然每一種物品都有**和重量,我們優先挑選那些單位**最高的是否可行呢?比如在下圖中,我們有3種物品,他們的重量和**分別是10, 20, 30 kg和60, 100, 120。

那麼按照單位**來算的話,我們最先應該挑選的是**為60的元素,選擇它之後,揹包還剩下50 - 10 = 40kg。再繼續前面的選擇,我們應該挑選**為100的元素,這樣揹包裡的總價值為60 + 100 = 160。所占用的重量為30, 剩下20kg。因為後面需要挑選的物品為30kg已經超出揹包的容量了。我們按照這種思路能選擇到的最多就是前面兩個物品。如下圖:

按照我們前面的期望,這樣選擇得到的價值應該是最大的。可是由於有乙個揹包重量的限制,這裡只用了30kg,還有剩下20kg浪費了。這會是最優的選擇嗎?我們看看所有的選擇情況:

很遺憾,在這幾種選擇情況中,我們前面的選擇反而是帶來價值最低的。而選擇重量分別為20kg和30kg的物品帶來了最大的價值。看來,我們剛才這種選擇最佳單位**的方式也行不通。 

既然前面兩種辦法都不可行,我們再來看看有沒有別的方法。我們再來看這個問題。我們需要選擇n個元素中的若干個來形成最優解,假定為k個。那麼對於這k個元素a1, a2, ...ak來說,它們組成的物品組合必然滿足總重量<=揹包重量限制,而且它們的價值必然是最大的。因為它們是我們假定的最優選擇嘛,肯定價值應該是最大的。假定ak是我們按照前面順序放入的最後乙個物品。它的重量為wk,它的價值為vk。既然我們前面選擇的這k個元素構成了最優選擇,如果我們把這個ak物品拿走,對應於k-1個物品來說,它們所涵蓋的重量範圍為0-(w-wk)。假定w為揹包允許承重的量。假定最終的價值是v,剩下的物品所構成的價值為v-vk。這剩下的k-1個元素是不是構成了乙個這種w-wk的最優解呢?

我們可以用反證法來推導。假定拿走ak這個物品後,剩下的這些物品沒有構成w-wk重量範圍的最佳價值選擇。那麼我們肯定有另外k-1個元素,他們在w-wk重量範圍內構成的價值更大。如果這樣的話,我們用這k-1個物品再加上第k個,他們構成的最終w重量範圍內的價值就是最優的。這豈不是和我們前面假設的k個元素構成最佳矛盾了嗎?所以我們可以肯定,在這k個元素裡拿掉最後那個元素,前面剩下的元素依然構成乙個最佳解。

現在我們經過前面的推理已經得到了乙個基本的遞推關係,就是乙個最優解的子解集也是最優的。可是,我們該怎麼來求得這個最優解呢?我們這樣來看。假定我們定義乙個函式c[i, w]表示到第i個元素為止,在限制總重量為w的情況下我們所能選擇到的最優解。那麼這個最優解要麼包含有i這個物品,要麼不包含,肯定是這兩種情況中的一種。如果我們選擇了第i個物品,那麼實際上這個最優解是c[i - 1, w-wi] + vi。而如果我們沒有選擇第i個物品,這個最優解是c[i-1, w]。這樣,實際上對於到底要不要取第i個物品,我們只要比較這兩種情況,哪個的結果值更大不就是最優的麼?

在前面討論的關係裡,還有乙個情況我們需要考慮的就是,我們這個最優解是基於選擇物品i時總重量還是在w範圍內的,如果超出了呢?我們肯定不能選擇它,這就和c[i-1, w]一樣。

另外,對於初始的情況呢?很明顯c[0, w]裡不管w是多少,肯定為0。因為它表示我們乙個物品都不選擇的情況。c[i, 0]也一樣,當我們總重量限制為0時,肯定價值為0。

這樣,基於我們前面討論的這3個部分,我們可以得到乙個如下的遞推公式:

有了這個關係,我們可以更進一步的來考慮**實現了。我們有這麼乙個遞迴的關係,其中,後面的函式結果其實是依賴於前面的結果的。我們只要按照前面求出來最基礎的最優條件,然後往後面一步步遞推,就可以找到結果了。

我們再來考慮一下具體實現的細節。這一組物品分別有價值和重量,我們可以定義兩個陣列int v, int w。v[i]表示第i個物品的價值,w[i]表示第i個物品的重量。為了表示c[i, w],我們可以使用乙個int[i][w]的矩陣。其中i的最大值為物品的數量,而w表示最大的重量限制。按照前面的遞推關係,c[i][0]和c[0][w]都是0。而我們所要求的最終結果是c[n][w]。所以我們實際中建立的矩陣是(n + 1) x (w + 1)的規格。

和前面使用動態規劃方法解決問題不一樣。因為這裡是部分揹包問題,我們可以採用前面討論過的乙個思路。就是每次選擇最優單位**的物品,直到達到揹包重量限制要求。

以前面的示例來看,我們按照這種方式選擇的物品結果應該如下圖:

現在,我們從實現的角度再來考慮一下。我們這裡的最優解是每次挑選價效比最高的物品。對於這一組物品來說,我們需要將他們按照價效比從最高到最低的順序來取。我們可能需要將他們進行排序。然後再依次取出來放入揹包中。假定我們已經有陣列v,w,他們已經按照價效比排好序了。

在前面我們挑選按照價效比排好序的物品時,排序消耗了主要的時間。在這裡,我們是否真的需要去把這些物品排序呢?在某些情況下,我們只要選擇一堆物品,保證他們物品重量在指定範圍內。如果我們一次挑出來一批這樣的物品,而且他們滿足這樣的條件是不是更好呢?這一種思路是借鑑快速排序裡對元素進行劃分的思路。主要過程如下:

1. 求每個元素的單位價值,pi = vi /wi。然後陣列按照pi進行劃分,這樣會被分成3個部分,l, m, n。其中l < m < n。這裡l表示單位價值小於某個指定值的集合,m是等於這個值的集合,而n是大於這個值的集合。

2. 我們可以首先看n的集合,因為這裡都是單位價值高的集合。我們將他們的重量累加,如果wn的重量等於我們期望的值w,則n中間的結果就是我們找到的結果。

3. 如果wn的重量大於w,我們需要在n集合裡做進一步劃分。

4. 如果wn的重量小於w,我們需要在n的基礎上再去l的集合裡劃分,找裡面大的一部分。

這樣重複步驟1到4.

這裡和快速排序的思路基本上差不多,只是需要將乙個分割的集合給記錄下來。其時間複雜度也更好一點,為o(n)。這裡就簡單的描述下思路,等後續再將具體的實現**給補上。

我們這裡討論的兩種揹包問題因為問題的不同其本質解決方法也不同。對於0-1揹包來說,他們構成了乙個最優解問題的基礎。我們可以通過從最小的結果集遞推出最終最優結果。他們之間構成了乙個遞迴的關係。而對於部分揹包問題來說,我們可以考慮用貪婪演算法,每次選擇當前看來最優的結果。最終也構成了乙個最優的結果。乙個小小的前提變化,問題解決的思路卻大不同。裡面的思想值得反覆體會。

**如下:

#include #include 

int f[10000],w[10000],v[10000

];int max(int x,int

y)int

main()

for(i=1;i<=m;i++)

}printf(

"%d\n

",f[t]);

return0;

}

校門外的樹(NOIP2005複賽 普及組 第二題)

總時間限制 1000ms 記憶體限制 65536kb 描述 某校大門外長度為l的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1公尺。我們可以把馬路看成乙個數軸,馬路的一端在數軸0的位置,另一端在l的位置 數軸上的每個整數點,即0,1,2,l,都種有一棵樹。由於馬路上有一些區域要用來建地鐵。這些區域用...

NOIP2005普及組第四題

題目描述 樂樂是乙個聰明而又勤奮好學的孩子。他總喜歡探求事物的規律。一天,他突然對數的正整數次冪產生了興趣。眾所周知,2的正整數次冪最後一位數總是不斷的在重複2,4,8,6,2,4,8,6 我們說2的正整數次冪最後一位的迴圈長度是4 實際上4的倍數都可以說是迴圈長度,但我們只考慮最小的迴圈長度 類似...

迴圈(NOIP2005普及組第四題)

迴圈 circle.pas circle.in circle.out noip2005普及組t4 lyoi20090321資訊學綜合模擬problem2 樣例輸入 32 2 樣例輸出 4 資料規模 對於30 的資料,k 4 對於全部的資料,k 100 思路 這個題我之前是在oj上做過的,也知道這是n...