最大遞增子序列

【題目】:
給定數組arr,返回arr的最長遞增子序列。
【例子】:
arr=[10,22,9,33,21,50,41,60,80],返回的最長遞增子序列爲[10,22,33,41,60,80]長度爲6

思路:動態規劃
dp[i]爲以下標爲i的元素結尾的子數組的長度。開始將dp所有元素初始化爲1。
爲得到dp[i],需向前遍歷,找到比a[i]小而且使dp[i]最大的那個數。

/*
. 生成長度爲N的數組dp, dp[i]表示在以arr[i]這個數結尾的情況下,arr[0...i]中的最大遞增序列長度。

2. 對第一個數arr[0]來說,令dp[0] = 1,接下來,從左到右依次計算出每個數結尾的情況下的最長遞增序列長度。

3. 計算dp[i],如果最長遞增子序列以arr[i]結尾,那麼arr[0,...,i-1]中所有比arr[i]小的數都可以作爲倒數第二個數

    所以 dp[i] = max{ dp[j] + 1} (0 <=j < i, arr[j] < arr[i]), 如果arr[0,...,i-1]中所有數都不比arr[i]小,令dp[i] = 1。

4.根據求出的dp數組,得到最長遞增子序列。遍歷dp數組,找到最大值以及位置,並開始逆序還原出決策路徑。

*/
#include "iostream"
#include "vector"
#include "algorithm"
using namespace std;

void findmax(int* a, int* dp)
{
	for (int i = 0; i < 9; i++)
		dp[i] = 1;
	for(int i = 1; i<9;i++)
		for (int k = 0; k < i; k++)
		{
			if(a[k] < a[i])
				dp[i] = max(dp[k] + 1, dp[i]);
		}
	
}
void main()
{
	vector<int> v;
	int a[] = { 2, 1, 5, 3, 6, 4, 8, 9, 7 };
	int *dp = new int[9];//以i結尾的公共序列長度
	findmax(a, dp);
	int len = 0, end = 0;
	for (int i = 0; i < 9; i++)
	{
		if (dp[i] > len) // 找到最長的並記錄索引
		{
			len = dp[i];
			end = i;
		}
	}
	cout << len << end<< endl;
	v.push_back(a[end]);
	for (int i = end - 1; i >= 0; i--)
	{
		if (a[i] < a[end] && dp[end] == dp[i] + 1)
		{
			v.push_back(a[i]);
			end = i;
		}
	}
	reverse(v.begin(), v.end());
	for (int i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	system("pause");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章