動態規划實現子數組和的最大值


/*
*copyright@nciaebupt 轉載請注明出處
*問題:輸入一個整型數組,數組里有正數也有負數。數組中一個或連續的多個整數組成一個子數組。
*求所有子數組的和的最大值。要求時間負責度為O(n)。
*使用動態規划方法來實現:
*如果用函數f(i)表示以第i個數字結尾的子數組的最大和,那么我們需要求出max(f[0...n])。
*我們可以給出如下遞歸公式求f(i)
*     |-- array[i] 如果i==0或者f(i-1)<0
*f(i)=|
*     |-- f(i-1) + array[i] 如果f(i-1)>0
*這個公式的意義:
*   當以第(i-1)個數字為結尾的子數組中所有數字的和f(i-1)小於0時,如果把這個負數和第i個數相加,得到的結果反而不第i個數本身還要小,所以這種情況下最大子數組和是第i個數本身。
*   如果以第(i-1)個數字為結尾的子數組中所有數字的和f(i-1)大於0,與第i個數累加就得到了以第i個數結尾的子數組中所有數字的和。
*/

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;

int maxSumInSubArray(int *array,int len)
{
    int *c = new int[len];//用來記錄以當前元素結尾(數組就到當前元素的位置為止)的子數組的最大和
    int max = -1000;//用來記錄數組c[]中的最大值
    int start = 0;//記錄數組中子數組的最大和的開始位置
    int end = 0;//記錄數組中子數組的最大和的結束位置
    int tmp = 0;

    c[0] = array[0];
    for(int i = 1;i < len;++i)
    {
        if(c[i-1] > 0)
        {
            c[i] = c[i-1] + array[i];
        }
        else
        {
            c[i] = array[i];
            tmp = i;
        }
        if(c[i] > max)
        {
            max = c[i];
            start = tmp;
            end = i;
        }
    }
    cout<<"子數組最大和的起始位置:"<<start<<"~"<<end<<endl;
    return max;
}

int main(int args,char ** argv)
{
    int array[] = {1,-2,3,10,-4,7,2,-5};
    int len = sizeof(array)/sizeof(int);
    int res = maxSumInSubArray(array,len);
    cout<<"子數組最大和: "<<res<<endl;
    system("pause");
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM