1. 程式人生 > 其它 >最大上升子序列和——簡單動態規劃

最大上升子序列和——簡單動態規劃

最大上升子序列和:

題目描述

一個數的序列bi,當b1 < b2 < ... < bS的時候,我們稱這個序列是上升的。對於給定的一個序列(a1, a2, ...,aN),我們可以得到一些上升的子序列(ai1, ai2, ..., aiK),這裡1 <= i1 < i2 < ... < iK <= N。比如,對於序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。這些子序列中序列和最大為18,為子序列(1, 3, 5, 9)的和. 你的任務,就是對於給定的序列,求出最大上升子序列和。注意,最長的上升子序列的和不一定是最大的,比如序列(100, 1, 2, 3)的最大上升子序列和為100,而最長上升子序列為(1, 2, 3)。

輸入描述:

輸入包含多組測試資料。

每組測試資料由兩行組成。第一行是序列的長度N (1 <= N <= 1000)。第二行給出序列中的N個整數,這些整數的取值範圍都在0到10000(可能重複)。

輸出描述:

對於每組測試資料,輸出輸出其最大上升子序列和。


解:

設一個序列b[]有n個數,dp[i]存放的對應第i個數及其之前的最大上升子序列和。比如:100,1,2,3 dp[0]=100, dp[1]=1, dp[2]=3, dp[3]=6;

把dp[i]的初始值設為序列第i個數的值,上述序列dp[i]的初始值為dp[0]=100, dp[1]=1, dp[2]=2, dp[3]=3;

在dp[]的初始值的基礎上,從前往後遍歷,上述序列中遍歷到3, ,1在3之前並且1小於3,那麼dp[3]=dp[1]+b[3],在遍歷到2時,dp[3]=dp[2]+b[3];

#include <iostream>
using namespace std;
typedef long long ll;
int main()
{
    ll n,dp[1001],a[1001];
    while(cin>>n)
    {
        for(int i=0; i<n; i++)
            cin>>a[i];
        
        dp[0] = a[0];
        for(int i=1; i<n; i++)
        {
            dp[i] = a[i];
            for(int j=0; j<i; j++)
            {
                if(a[i]>a[j])
                    dp[i] = max(dp[i],dp[j]+a[i]);
            }
        }
        ll ans = -1;
          for(int i=0; i<n; i++)
              ans = max(ans,dp[i]);
        cout<<ans<<endl;
    }
    return 0;
}