/*
最长递增子序列A
给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)
例如:给定一个长度为8的数组A{1,3,5,2,4,6,7,8},则其最长的单调递增子序列为{1,2,4,6,7,8},长度为6.
输入描述:
第一行包含一个整数T,代表测试数据组数。
对于每组测试数据:
N-数组的长度
a1 a2 ... an (需要计算的数组)
保证:
1<=N<=3000,0<=ai<=MAX_INT.
输出描述:
对于每组数据,输出一个整数,代表最长递增子序列的长度。
输入例子:
2
7
89 256 78 1 46 78 8
5
6 4 8 2 17
输出例子:
3
3
*/
#include<iostream>
#include<vector>
#include<list>
#include<fstream>
#include<string>
#include<unordered_set>
#include<map>
#include<algorithm>
#include<stack>
using namespace std;
int TheLonggestIncreasingSubsequence(vector<int>&data){
int size = data.size();
vector<int>tmp(size, 0);
vector<vector<int>>max, p;
int re = 1;
for (int i = 0; i < size; i++){
p.push_back(tmp);
p[i][i] = 1;
max.push_back(tmp);
max[i][i] = data[i];
}
//开始填表
for (int i = 0; i < size; i++){
for (int j = i + 1; j < size; j++){
if (data[j]>max[i][j - 1]){
p[i][j] = p[i][j - 1] + 1;
max[i][j] = data[j];
}
else {
p[i][j] = p[i][j - 1];
max[i][j] = max[i][j - 1];
}
if (p[i][j]>re)re = p[i][j];
}
}
return re;
}
int main(){
string str;
int num, temp, k;
vector<int>data;
cin >> num;
while (num){
cin >> temp;
for (int i = 0; i < temp; i++){
cin >> k;
data.push_back(k);
}
cout <<TheLonggestIncreasingSubsequence(data) << endl;
data.clear();
num--;
}
}
解析:
思路:利用两个矩阵p和max,p[i][j]保存从任意点i到j之间的最大递增序列长度,max[i][j]保存从i到j最大递增子序列的最大数,若第i个数大于max[i][j-1]则递增子序列加1,则p[i][j]=p[i][j]+1,否则不变,在填写表格的时候是横向填写.
但是提示内存超出限制。可以做如下修改:
只用一个一维数组来保存dp[size]来保存最长递增子序列的个数,每次都从第i个位置填写!!