最大子數組問題(動態規劃)--【算法導論】

前些天學車...真是相當累啊,比上課累,現在終於可以休息了...

重新看《算法導論》,不過這下可得認真看了,9個月不到就得去找工作了,與我同樣的大三黨們一樣加油咯...

《算法導論》中引入這個問題是通過股票的購買與出售,將前一天的當天的股票差價重新表示出來,即轉爲了一個最大子數組的問題,具體內容我不多說,轉的內容是:

13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7

找到這連續的16個數裏面的連續和最大的子數組;

書中練習部分說用設計非遞歸的,線性時間的算法,我就YY爲動態規劃處理了;

從數組的左邊界開始,從左至右處理,記錄到目前爲止已經處理過的最大子數組。若已知A[1..j]的最大子數組,基於如下性質將解擴展爲A[1...j+1]的最大子數組:A[1...j+1]的最大子數組要麼是A[1...j]的最大子數組,要麼是某個子數組A[i...j+1](1<=i<=j+1)。在已知A[1...j]的最大子數組的情況下,可以在線性時間內找出形如A[i...j+1]的最大子數組;

思想上述都將出來了,只要將關鍵點寫出即可:

如果前面若干和<0,則其對後面子數組相加無幫助,此時重置dparray[i],並且記錄的起始位置重新標記;

        if(dp[i - 1] <= 0)  //前面的<0,直接丟棄
        {
            dp[i] = array[i];
            temp = i; //記錄起始爲止
        }

否則,繼續往後延伸;

dp[i] = array[i] + dp[i - 1];  //往後求和

最後判斷最大子數組值就行,同時標記起始與結束位置

        if(dp[i] > MaxSumSub)  //找到到i爲止的最大子數組
        {
            MaxSumSub = dp[i];  //最大...
            start = temp;  //標記起始
            end = i;  //標記此時的結束位置
        }


代碼:

#include <iostream>

using namespace std;

int FindMaxSubarray(int array[], int length)
{
    int start = 0, end = 0;  //記錄最大子數組的起始位置(在數組中的下標)
    int MaxSumSub;  //最大子數組的值
    int* dp = new int[length];  //動態規劃記錄

    dp[0] = array[0];  //初始爲第一個數
    MaxSumSub = dp[0];  //最大值初始爲第一個數
    int temp = 0;  //

    for(int i = 1; i < length; i++)
    {
        if(dp[i - 1] <= 0)  //前面的<0,直接丟棄
        {
            dp[i] = array[i];
            temp = i; //記錄起始爲止
        }
        else
            dp[i] = array[i] + dp[i - 1];  //往後求和

        if(dp[i] > MaxSumSub)  //找到到i爲止的最大子數組
        {
            MaxSumSub = dp[i];  //最大...
            start = temp;  //標記起始
            end = i;  //標記此時的結束位置
        }
    }

    cout<<"最大子序列的下標:"<<start<<"->"<<end<<endl;
    return MaxSumSub;

}

int main()
{
    int a[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
    //int a[] = {23, 4};
    int length = sizeof(a) / sizeof(int);

    cout<<FindMaxSubarray(a, length);
    return 0;
}

 

最大子序列即爲{18, 20, -7, 12};

上述dp即爲動態記錄尋找最大子數組的過程,大家也可以進行輸出看一下;

 

歡迎大家指點,o(∩_∩)o

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