動態規劃經典入門級題目*2及詳解

題目來自極客學院的視頻教程-動態規劃(一)

一句話解釋動態規劃:多階段最優化決策解決問題的過程

解題技巧:只關注狀態轉移(子問題之間的關係),不要考慮某個狀態是怎麼出現的


1.字符串解碼

一個只包含大寫字母的字符串加密後變成了只包含數字的字符串,加密的規則:

'A' -> 1

'B' -> 2

...

'Z' -> 26

現在給定一個只包含數字的加密過的字符串,求該字符串有多少種解密的方法。例如“12”->"AB", "12"->"L"


解:2位的在26以內的相鄰的數可以產生不同的解,字符串用str表示,用一維數組dp[i]來表示從0到i位解碼方法總數,dp[0]=1,想從dp[i]得到dp[i+1]:

1.str[i+1]是‘0’,那麼他不能單獨譯成一個字母,一定是和str[i]組合,dp[i+1] = dp[i-1]

2.str[i+1]不是‘0’:  

   1)str[i]和str[i+1]位不能組成一個字母,將str[i+1]解碼爲對應的字母,dp[i+1] = dp[i]

   2)str[i]和str[i+1]可以組和譯成一個字母,則在這裏就可以出現2種解碼方法,如果單獨譯dp[i+1],有dp[i]種方法,如果組合起來,有dp[i-1]種方法,那麼dp[i+1] = dp[i]+dp[i-1]

代碼:

int Decode_num(string& str) {
    int len = str.length();
    int *dp = new int[len];
    dp[0] = 1;
    if (str[1] == '0') dp[1] = 1;
    else if (str[0] == '1' || (str[0] == '2' && str[1] <= '6')) dp[1] = 2;
    else dp[1] = 1;
    for (int i = 1; i < len-1; i++) {
	if (str[i+1] == '0') dp[i+1] = dp[i-1];
        else if (str[i] == '1' || (str[i] == '2' && str[i+1] <= '6')) dp[i+1] = dp[i] + dp[i-1];
        else dp[i+1] = dp[i];
    }
    return dp[len-1];
}


2.最大子數組乘積

給定一個整數數組,求乘積最大的子數組的乘積值


解:

1)首先明確數組中的數可能是負數

2)設數組是vec[],這裏我們在for循環中用一個max和min值分別記錄包含0~i中包含vec[i]的子數組的乘積的最大值和最小值,爲什麼一定是包含vec[i]呢,因爲只有在這個定義之下,我們才能由i計算到i+1

3)那麼包含vec[i]的子數組乘積的最大值就是vec[i],vec[i]*max,vec[i]*min中的最大值(當min和vec[i]同爲負,相乘得到最大值),更新max值

4)循環中同時更新min,min就是vec[i],vec[i]*max,vec[i]*min中的最小值

5)返回的結果max_product,是以0~size-1結尾的子數組乘積最大值的最大值

代碼:

int Max_product(vector<int>& vec) {
    int size = vec.size();
    int max_product = vec[0];
    int _min = vec[0];
    int _max = vec[0];
    for (int i = 1; i < size; i++) {
        int copy_max = _max;
        _max = max(max(vec[i], vec[i]*_max), vec[i]*_min);
        _min = min(min(vec[i], vec[i]*_min), vec[i]*copy_max);
        max_product = max(max_product, _max);
    }
    return max_product;
}



發佈了55 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章