HDU1087 超级跳跃(递增子序列最大和)【DP经典】

题目链接:https://vjudge.net/contest/124428#problem/D

题目大意:
在给定的序列中求最大递增子序列之和

解题分析:

显然这道题用动态规划来解决

不难知道整体最优解与局部最优解的关系为:dp[i] = dp[j] + a[i]  其中dp[i]表示第i个元素的最长递增子序列和,j为小于a[i]的序号最大的数a[j]的下标

详细解析:如序列:1 4 7 3 5 6,那么开一个数组来保存同下标的“最大值”,每一个都要向前找合法的最大dp值,如这里的5可以找的合法值为3 4 1,找到最大后便加上同下标的a值,如:

数组a:   1 4  7  3  5   6

数组dp1 5 12 4 10 16

这样就可以从dp数组中找到最大值了。

#include <iostream>
using namespace std;
int main()
{
    int n, a[1005], dp[1005], sum;         //dp数组表示以i为结尾的最大递增子序列之和
    while (cin >> n, n)
    {
        for (int i = 0; i < n; i++)
            cin >> a[i];
        sum = dp[0] = a[0];
        for (int i = 1; i < n; i++)
        {
            dp[i] = a[i];
            for (int j = 0; j < i; j++)
                if (a[j] < a[i] && dp[j] + a[i] > dp[i])         //j为小于a[i]的学号最大的数的下标
                    dp[i] = dp[j] + a[i];
            if (sum < dp[i])
                sum = dp[i];
        }
        cout << sum << endl;
    }
    return 0;
}

2018-04-29

猜你喜欢

转载自www.cnblogs.com/00isok/p/8972102.html