动态规划2)最大连续子序列和和最长不下降子序列

1.最大连续子序列和问题就是:给定一个数字序列a1,a2,a3,a4……an,求i,j(1<=i<=j<=n),使ai+……+aj的和最大,找出最大和。

比如一个序列: -1 10 -2 12 -3 -1
他的最大连续子序列和就是10+(-2)+12=20
用动态规划来处理:假设dp[i]表示以ai作为结尾的连续序列的最大和。比如:
dp[0]=-1;
dp[1]=10;
dp[2]=10+(-2)=8;
dp[3]=10+(-2)+12=20;
dp[4]=10+(-2)+12+(-3)=17;
dp[5]=10+(-2)+12+(-3)+(-1)=16;
dp[i]有两种情况:
1.dp[i]只有a[i]一个元素,这种情况dp[i]就是a[i];
2.dp[i]有多个元素。最大和就是dp[i-1]+a[i]
状态转移方程:dp[i]=max(dp[i-1]+a[i],a[i])
边界就是dp[0]=0,所以写代码的时候就从0开始依次用状态转移方程推出后面的dp[]。

2.最长不下降子序列(LIS):在一个数字序列中找到一个最长的子序列(可以不连续!),让这个序列是递增的。
这个问题要比最大连续子序列复杂一些。我们还是用dp[i]来表示以a[i]结尾的最长不下降子序列。我们用一道例题来具体说明。
在这里插入图片描述
在这里插入图片描述
这两种情况就是最大和的情况:
在这里插入图片描述在这里插入图片描述
用图来分析做法:
在这里插入图片描述
我们可以自己先找出来每一个dp[],做一个分析:
在这里插入图片描述
我们简单分析一下前几个:
在这里插入图片描述
在这里插入图片描述
代码实现:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
	int n;
	scanf("%d",&n);
	int a[n+1];
	int dp[n+1];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	int ans=-1;//用来找dp[]中的最大值,题目要求输出最大值
	for(int i=0;i<n;i++)
	{
		dp[i]=1;//每一个起始的长度时候都是1
		for(int j=0;j<i;j++)//在i前面找
		{
			if(a[i]>=a[j]&&dp[j]+1>dp[i])
			{
				dp[i]=dp[j]+1;
			}
		}
		ans=max(dp[i],ans);//找到最大dp[]值
	}
	printf("%d",ans);
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天金小麻花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值