题目描述:
这里是广场上站着一支队伍,她们是来自全国各地的扭秧歌代表队,现在有她们的身高数据,请你帮忙找出身高依次递增的子序列。 例如队伍的身高数据是(1、7、3、5、9、4、8),其中依次递增的子序列有(1、7),(1、3、5、9),(1、3、4、8)等,其中最长的长度为4。
链接:https://www.nowcoder.com/questionTerminal/d83721575bd4418eae76c916483493de
来源:牛客网
输入描述:
输入包含多组数据,每组数据第一行包含一个正整数n(1≤n≤1000)。
紧接着第二行包含n个正整数m(1≤n≤10000),代表队伍中每位队员的身高。
输出描述:
对应每一组数据,输出最长递增子序列的长度。
解题思路:
1、什么是递增子序列?
例:有一个序列{9,4,5,2,8,1,6}
其中{4,5,8}、{5,2,1,6}等都是原序列的递增子序列
注意:这里子序列不一定要连续!!!
2、给这个序列每一个数做一个标记dp[i],它的值表示当前这个数字的前面有多少个数字(按照递增序列)小于它。
3、怎么实现dp[i]的技术?
比如现在为第i个数据,那么从第一个数据找比它小的数据;
(1)找到第一个比它小的数据k,则数据i的dp[i]+1;
(2)找到第二个比它小的数据m,比较数据i的dp[i]与m的 dp[m]+1谁大,若dp[m]+1>dp[i],则将dp[m]+1赋给dp[m];
(在所有比它小的数字中挑选dp[]值最大的(即序列长度最长的),给其+1赋给自己;这样就保证了我所在的序列长度最长)
(3)依次类推,得到dp[m]
4、在数组dp中找到最大值并输出即可
代码:
#include<iostream>//LIS最长上升子序列
#include<vector>
using namespace std;
int main()
{
int n;
while (cin >> n)
{
vector<int>temp(n);
vector<int>dp(n);
int maxlenth = 0;
for (int i = 0; i < n; i++)
{
cin >> temp[i];
}
for (int i = 0; i < n; i++)
{
dp[i] = 1;
}
for (int i = 1; i < n;i++)
{
for (int j = 0; j < i; j++)
{
if ((temp[j] < temp[i])&&(dp[j]+1>dp[i]))
{
dp[i] = dp[j] + 1;
}
}
}
for (auto &i : dp)
{
if (i>maxlenth)
{
maxlenth = i;
}
}
cout << maxlenth << endl;
}
system("pause");
return 0;
}