hdu 1087

本文探讨了一道经典的动态规划问题:给定一系列整数,找出严格上升子序列的最大和。通过详细的算法解析和C++代码实现,展示了如何有效地解决这个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目概述

给定N个数构成的序列,求严格上升子序列中元素和的最大值

时限

1000ms/2000ms

输入

每行第一个正整数N,其后N个整数,为序列中的数,输入到N=0为止

限制

1<=N<=1000;序列中的数皆在32位整型范围内

输出

每行一个数,所求的和的最大值

样例输入

3 1 3 2
4 1 2 3 4
4 3 3 2 1
0

样例输出

4
10
3

讨论

dp,最大上升子序列和,阶段,遇到的每一个数,状态,以该数结尾的上升子序列和,决策,将其加入之前某子序列的和,或以自身作为新序列,子问题,以遇到的数结尾的上升子序列和,子问题边界,以第一个数结尾的上升子序列和,无后效性确认,之前选择的数只能影响到自己为止的上升子序列和,确定参数,上升子序列和,子序列结尾的数,遇到的数自身,注意到这是一个带条件的dp,需要大于结尾的数才能加和,因而可能无法从上一阶段直接得到现阶段的解,需要考虑之前所有阶段的解并取最大者,加上自身作为自身的最优解,因而需要一个一维数组记录之前阶段的最优解,该数组为dp,基本思路便是如此,下面处理细节问题
题目要求必须是严格上升子序列,故需要修改条件,至此,思路已经明了,可以出代码了

题解状态

31MS,1720K,628B,C++

题解代码

#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 1003
#define memset0(a) memset(a,0,sizeof(a))

int nums[MAXN], dp[MAXN];//存放每个数自身 存放上升子序列的和
int fun(int N)
{
    int most = 0;//初始化最大和
    for (int p = 0; p < N; p++) {
        scanf("%d", &nums[p]);//input
        dp[p] = nums[p];//初始化dp为自身 因为无法在之后完成此步骤 同时由于这一步 不再需要额外清零dp数组
        for (int i = p; i >= 0; i--)
            if (nums[p] > nums[i])//限制条件 大于子序列最后一个元素
                dp[p] = max(dp[p], dp[i] + nums[p]);//转移方程
        most = max(most, dp[p]);//记录最大上升子序列和
    }
    return most;
}
int main(void)
{
    //freopen("vs_cin.txt", "r", stdin);
    //freopen("vs_cout.txt", "w", stdout);

    int N;//元素个数
    while (~scanf("%d", &N) && N)
        printf("%d\n", fun(N));//output
}

EOF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值