一.最长连续递增子序列
Q:输入一个数组,求数组中连续递增子序列的最大长度
输入:5 ,{1,3,4,2,7}
输出:3 (最长递增子序列为{1,3,4})
解题思路:
- 题目要求子序列连续,可以从起始位置开始一直向后判断,如果后一个位置大于该位置,则继续向后判断并记录长度;
- 如果出现后一个位置小于前一个位置,那么就不必再向后判断,此时的长度就是以该起始位置开始的连续递增子序列的长度;
- 将长度与最大长度进行比较,更新最大长度;
代码实现:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
while (cin >> n)
{
int num;
vector<int> v(n, 0);
for (int i = 0; i < n; ++i)
{
cin >> num;
v[i] = num;
}
int count = 0;
for (int i = 0; i < n-1; ++i)
{
int s1 = v[i];
int tmp = 1;
for (int j = i + 1; j < n; ++j)
{
if (s1 < v[j])
{
++tmp;
s1 = v[j];
}
else //如果后一个位置小于前一个,则不需要向后再判断
break;
}
count = max(count, tmp); //更新最大长度
}
cout << count << endl;
}
}
结果验证:
二.最长递增子序列(可不连续)
Q:输入一个数组,求数组中递增子序列的最大长度
输入:8 ,{5,1,6,8,2,3,5,8}
输出:5 (最长递增子序列为{1,2,3,5,8})
解题思路:
- 由于子序列可以不连续,可以使用最长公共子序列法做
- 先将原数组排序后,求出新旧数组的最长公共子序列长度即为最长递增子序列长度
- 如果不清楚最长公共子序列的求法,可以参考一下我之前的一篇博客
博客?:最长公共子序列问题(动态规划)
代码实现:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
while (cin >> n)
{
int num;
vector<int> res(n);
vector<int> tmp(n);
for (int i = 0; i < n; ++i)
{
cin >> num;
res[i] = num;
tmp[i] = num;
}
sort(tmp.begin(), tmp.end());
vector<vector<int>> dp(n, vector<int>(n, 0));
if (res[0] == tmp[0])
dp[0][0] = 1;
for (int i = 1; i < n; ++i)
{
if (res[0] == tmp[i])
dp[0][i] = 1;
dp[0][i] = max(dp[0][i], dp[0][i - 1]);
}
for (int i = 1; i < n; ++i)
{
if (res[i] == tmp[0])
dp[i][0] = 1;
dp[i][0] = max(dp[i][0], dp[i - 1][0]);
}
for (int i = 1; i < n; ++i)
{
for (int j = 1; j < n; ++j)
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
if (res[i] == tmp[j])
dp[i][j] = max(dp[i][j],dp[i - 1][j - 1] + 1);
}
}
cout << dp[n - 1][n - 1];
}
}
结果验证: