最大上升子序列和——簡單動態規劃
阿新 • • 發佈:2021-02-17
最大上升子序列和:
題目描述
一個數的序列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; }