POJ——2479 Maximum sum(dp)

题意:

求一个数列内不相交的两个数列的最大和。

思路:

之前做过求最大子序列和的题目,利用dp。但是这道题目是两段不相交的数列,我们可以从前到后和从后到前进行两次dp,然后便可以求出他们的最大和。

dp关系式如下:

dp1[i] = max(dp1[i-1] + num[i],num[i]);//限制了num[i]一定参与,保证了数列的连续性

dp2[i] = max(dp2[i+1] + num[i],num[i]);

这里注意dp[i]的定义为包含第i个元素的最大数列和,所以在处理dp2的时候我们可以利用一个tmp维护最大子数列的值,也就是说可以在更新dp2的同时把两个数列的最大和求出。

代码实现:

#include 
#include 
#include 
#include 

using namespace std;

const int MAX = 50010;
const int INF = 0x7f7f7f7f;

int T;
int N;
int res;
int num[MAX];
int dp1[MAX];
int dp2[MAX];
int main()
{
    scanf("%d",&T);
    while( T-- ){
        scanf("%d",&N);
        for( int i = 0; i < N; i++ ){
            dp1[i] = dp2[i] = -INF;
        }
        for( int i = 0; i < N; i++ ){
            scanf("%d",&num[i]);
        }
        res = -INF;
        dp1[0] = num[0];
        dp2[N-1] = num[N-1];
        for( int i = 1; i < N; i++ ){
            dp1[i] = max(dp1[i-1]+num[i],num[i]);
        }
        int tmp = num[N-1];
        for( int i = N-2; i >= 0; i-- ){
            dp2[i] = max(dp2[i+1]+num[i],num[i]);
            tmp = max(tmp,dp2[i+1]);
            res = max(res,dp1[i]+tmp);
        }
        printf("%d\n",res);
    }
    return 0;
}


你可能感兴趣的:(动态规划)