動態規劃:連續最大和

最簡單和經典的一維和線性dp:

斐波那契和連續最大和問題:

把多階段過程轉化爲一系列單階段問題,利用各階段之間的關係,逐個求解,創立了解決這類過程優化問題的新方法——動態規劃。

暴力遞歸:

1,把問題轉化爲規模縮小了的同類問題的子問題 
2,有明確的不需要繼續進行遞歸的條件(base case) 
3,有當得到了子問題的結果之後的決策過程 
4,不記錄每一個子問題的解。

而我們需要把這種遞歸思路轉換爲動態規劃

遞歸到動規的一般轉化方法

   1 遞歸函數有n個參數,就定義一個n維的數組

   2 數組的下標是遞歸函數參數的取值範圍

   3 數組元素的值是遞歸函數的返回值,這樣就可以從邊界值開始, 逐步填充數組,相當於計算遞歸函數值的逆過程。

    1. 將原問題分解爲子問題

  把原問題分解爲若干個子問題,子問題和原問題形式相同或類似,只不過規模變小了。子問題都解決,原問題即解決 子問題的解一旦求出就會被保存,所以每個子問題只需求 解一次。

    2.確定狀態    整個問題的時間複雜度是狀態數目乘以計算每個狀態所需時間。

    3.確定一些初始狀態(邊界狀態)的值

    4. 確定狀態轉移方程

     定義出什麼是“狀態”,以及在該“狀態”下的“值”後,就要找出不同的狀態之間如何遷移――即如何從一個或多個“值”已知的 “狀態”,求出另一個“狀態”的“值”(遞推型)。狀態的遷移可以用遞推公式表示,此遞推公式也可被稱作“狀態轉移方程”。

//斐波那契
class Solution {
public:
    int Fibonacci(int n) {
        if(n==0)
            return 0;
        if(n==1||n==2)
            return 1;
        int first=1,second=1;
        for(int i=2;i<n;i++)
        {
            int temp=second;
            second=first+second;
            first=temp;
             
        }
        return second;
    }
};
//連續最大和
#include <iostream>
#include <vector>
using namespace std;
int fun(vector<int> & v)
{
    int max=v[0];
    int ret=max;
    for(int i=1;i<v.size();i++)
    {
        max=std::max(max,0)+v[i];
        ret=std::max(ret,max);
    }
    return ret;
}
int main()
{
    int n;
    while(cin>>n)
    {
        vector<int> v;
        v.reserve(n);
        while(n--)
        {
            int num;
            cin>>num;
            v.push_back(num);
        }
        cout<<fun(v)<<endl;
    }
    
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章