很经典的一道题,典型的动态规划方法的体现,这道题有一个简单的变形,我们先看看这个简单的变形。
变形:找到一个数组的最长连续子序列是的其和最大,并输出这个最大值
例如:
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,返回那个最大的即可!
利用容器的思想更容易解决!