找一个数组的最大上升子序列(允许不连续)

很经典的一道题,典型的动态规划方法的体现,这道题有一个简单的变形,我们先看看这个简单的变形。


变形:找到一个数组的最长连续子序列是的其和最大,并输出这个最大值

例如:

Input:

1,-3,5,-7,8,9,1,2,5,-10,3

Output:

25


本题的思路很简单,代码如下:

#include <iostream>

using namespace std;

int findMax(int *p, int n)
{
	int max = 0;
	int i = 0;
	int max1 = 0;
	while(i< n)
	{
		max1 = max1 + p[i];    //{1,-3,5,-7,8,9,1,2,5,-10,3}
		if(max1 < 0)
		{
			++i;
			max1 = p[i];
			max = max1;
			++i;
		}
		else
		{
			if(max1 > max)
				max = max1;
			i++;
		}
	}
	return max;
}

int main()
{
	int a[] = {8,-9,3,5,-7,12};//{1,-3,5,-7,8,9,1,2,5,-10,3};
	int length = 6;
	cout << findMax(a,length) <<endl;
	system("PAUSE");
	return 0;
}

我们需要做的就是设置一个当前的最大值max1与整体最大值max,每当max1小于0时就重新赋下一个值,当max1大于max时更新max即可。


现在回到我们的题,我先给出代码,之后再做讲解:

代码如下:

//最大上升子序列
#include <iostream>
#include <vector>

using namespace std;

//设置每个数的结构体
struct Info{
	int index;
	int a;
	int length;
};

//构造存储容器
vector<Info> v;

//找最大上升子序列
int findMax(int *p, int length)
{
	Info info;
	v.clear();
	int n = 0;
	int e;
	int m = 0;
	for(int i = 0; i < length; i++)
	{
		//初始化每个v[i]
		e = p[i];
		n++;
		v.push_back(info);
		v[n-1].a = e;
		v[n-1].index = n;
		if( n == 1)
		{
			v[n-1].length = 1;
			continue;
		}
		//计算每个v[i]的最大length
		m = 0;
		for(int k = 0; k < n; k++)
		{
			if(v[k].a < e)
			{
				if(v[k].length > m)
					m = v[k].length;
			}
		}
		v[n-1].length = m+1;
	}

	//返回那个最大的length
	m = 0;
	for(int p = 0; p < n; p++)
		if(v[p].length > m)
			m = v[p].length;
	return m;
}

int main()
{
	int a[] = {1,7,3,5,9,4,8};
	int b = 7;
	cout<<findMax(a,b)<<endl;
	system("PAUSE");
	return 0;
}

现在我来讲解一下思路:

首先设置一个结构体,index代表序号,从1开始,a代表值,length代表该值为终点的最大上升子序列的长度,思路就是当该a值大于前某个a值时,本a值的length即为前方离他最近的a的length+1,最后扫一边每个index的length,返回那个最大的即可!

利用容器的思想更容易解决!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值