1. 程式人生 > 其它 >動態規劃 洛谷P1616 瘋狂的採藥

動態規劃 洛谷P1616 瘋狂的採藥

動態規劃 洛谷P1616 瘋狂的採藥

同樣也是洛谷的動態規劃一個普及-的題目,接下來分享一下我做題程式碼

看到題目,沒很認真的看資料大小,我就提交了我的程式碼:

 1 //動態規劃 洛谷P1616 瘋狂的採藥
 2 #include<iostream>
 3 #include<cmath>
 4 using namespace std;
 5 int value[10005];//價值陣列
 6 int times[10005];//時間陣列
 7 int dp[10000003];//t的範圍1e7
 8 int main()
 9 {
10     int m, t;//m是數目,t是時間
11     cin >> t >> m;
12 for (int i = 1; i <= m; ++i) 13 { 14 cin >> times[i] >> value[i];//輸入資料 15 } 16 //從小遍歷到大進行規劃 因為這題可以選無數個一樣的 17 for (int i = 1; i <= t; ++i) 18 { 19 for (int j = 1; j <= m; ++j)//對每一種草藥進行遍歷 20 { 21 if (i >= times[j])//前提是時間大於採摘所需要的時間才能考慮
22 { 23 dp[i] = max(dp[i], dp[i - times[j]] + value[j]); 24 } 25 } 26 } 27 cout << dp[t]; 28 return 0; 29 30 }

 

測試了幾個測試用例,過了 ,於是乎,我就自信滿滿的提交了!

但是!

 

 

 

仔細觀察資料大小,經典的沒開long long 

於是改正:

 1 //動態規劃 洛谷P1616 瘋狂的採藥
 2 #include<iostream>
 3
#include<cmath> 4 using namespace std; 5 int value[10005];//價值陣列 6 int times[10005];//時間陣列 7 long long dp[10000003];//t的範圍1e7 long long !!!! 8 int main() 9 { 10 int m, t;//m是數目,t是時間 11 cin >> t >> m; 12 for (int i = 1; i <= m; ++i) 13 { 14 cin >> times[i] >> value[i];//輸入資料 15 } 16 //從小遍歷到大進行規劃 因為這題可以選無數個一樣的 17 for (int i = 1; i <= t; ++i) 18 { 19 for (int j = 1; j <= m; ++j)//對每一種草藥進行遍歷 20 { 21 if (i >= times[j])//前提是時間大於採摘所需要的時間才能考慮 22 { 23 dp[i] = max(dp[i], dp[i - times[j]] + value[j]); 24 } 25 } 26 } 27 cout << dp[t]; 28 return 0; 29 30 }

 

然後!

 

 

結束啦!

 

總結歸納一下: 這題和P1048 [NOIP2005 普及組] 採藥 非常像,只是資料加強了些,而且我們對比可以發現,還有一個區別就是每個藥可以採摘無數次。

於是我們歸納出一個模板,像只能採摘一次,也就是選擇一次的揹包問題,我們用採摘時間time值來做外層迴圈,反正每次只能選擇一次,也就是拿每種草藥的時間來遍歷.

//也就是
for(int i=1;i<=m;++i)
{
for(int j=x(揹包的最大容量),j>=time[i],--j)
{
dp[j]=max(dp[j],dp[j-time[i]]+value[i]);
}
}

但是像這一題,每次可以選擇無數次,我們外層迴圈就只能用時間了,有點像選硬幣湊錢問題。從1一直遍歷到最大的time。內層去遍歷每一種草藥,因為可以採摘多次,得出我們的模板:

for (int i = 1; i <= t(最大時間); ++i)從小到大隊每一個時間進行dp 算出每一個時間的最優解
    {
        for (int j = 1; j <= m(可供選擇的種類數); ++j)//對每一種草藥進行遍歷
        {
            if (i >= times[j])//前提是時間大於採摘所需要的時間才能考慮
            {
                dp[i] = max(dp[i], dp[i - times[j]] + value[j]);
            }
        }
    }