算法设计 最长递增子序列问题

算法设计 最长递增子序列问题

1. 问题描述
求一个由n个整数组成的整数序列的最长递增子序列。一个整数序列的递增子序列可以是序列中非连续的数按照原序列顺序排列而成的。 最长递增子序列是其递增子序列中长度最长的。
2. 具体要求
输入:输入的第一行是一个正整数n,表示测试例个数。接下来几行是n个测试例的数据,每个测试例的数据由两行组成,其中第一行为一个正整数k (k<=500),表示整数序列的长度,第二行给出整数序列,整数之间用一个空格隔开。(设给出的每个整数序列的最长递增子序列都是唯一的。)
输出:对于每个测试例输出两行,第一行为最长递增子序列的长度,第二行为最长递增子序列,整数之间用一个空格隔开。两个测试例的输出数据之间用一个空行隔开。
3. 测试数据
输入:
2
5
3 1 4 2 3
6
1 3 9 5 2 6
输出:
3
1 2 3

4
1 3 5 6

代码:

/// 
/// 输出最长子序列
/// 
/// 数据数组
/// 最短子序列前置点的数组
/// 要求的最长子序列的最后一位的下标
void printLongest(int* arr, int* pre, int i)
{
	if (pre[i] == -1)
	{
		cout << arr[i] << " ";
	}
	else 
	{
		printLongest(arr, pre, pre[i]);
		cout << arr[i] << " ";
	}
}

void test1()
{
	int n, k;
	cin >> n;
	while (n--)
	{
		cin >> k;
		int* arr = new int[k];	// 数据数组
		int* len = new int[k];	// 存放 当前求得的最短子序列长度 的数组
		int* pre = new int[k];	// 存放 当前求得的最短子序列中下标对应数据的前一个数据的下标 的数组
		for (int i = 0; i < k; i++)
		{
			cin >> arr[i];
			len[i] = 1;	// 初始时最长子序列只有自身到自身,长度为1
			pre[i] = -1;	//初始时没有前一个数据
		}
		for (int i = 0; i < k; i++)
		{
			for (int j = 0; j < i; j++)
			{
				if (arr[j] < arr[i])	// 如果前面有数据比当前数据小
				{
					if (len[i] < len[j] + 1)	// 判断如果它的最短子序列+1(加上当前数据)比自身现在的最长子序列还长
					{	// 将其替换为当前数据的最长子序列
						len[i] = len[j] + 1;
						pre[i] = j;
					}
				}
			}
		}
		int longestIndex = max_element(len, len + k) - len;
		cout << len[longestIndex] << endl;
		printLongest(arr, pre, longestIndex);
		cout << endl;
	}
}

截图:
算法设计 最长递增子序列问题_第1张图片

你可能感兴趣的:(算法设计,算法,c++,动态规划)