题目:POJ 2533 Longest Ordered Subsequence
Description
A numeric sequence of
ai is ordered if
a1 <
a2 < ... <
aN. Let the subsequence of the given numeric sequence (
a1,
a2, ...,
aN) be any sequence (
ai1,
ai2, ...,
aiK), where 1 <=
i1 <
i2 < ... <
iK <=
N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
思路1:最常用的方法是二维的动态规划,dp[i]表示0~i以data[i]结尾的最长递增子序列,则dp[i]等于所有data[i]前面的且比data[i]小的数的最长递增子序列的最大值加1,即dp[i] = max(dp[j]+1,1),其中{j < i && data[j] < data[i]},具体代码如下:
#include<iostream>
#include<vector>
using namespace std;
int LIS(vector<int> data)
{
int length = data.size(),i,j,res = 1;
if(length == 0)return 0;
vector<int> dp(length,1);
for(i = 1; i < length;++i)
{
for(j = 0;j < i;++j)
{
if(data[j] < data[i] && dp[j] + 1 > dp[i])dp[i] = dp[j] + 1;//状态转移方程
}
if(dp[i] > res)res = dp[i];
}
return res;
}
int main()
{
int n,i;
while(cin >> n)
{
vector<int> data(n);
for(i = 0; i < n;++i)cin >> data[i];
cout << LIS(data) << endl;
}
return 0;
}
#include<iostream>
#include<vector>
using namespace std;
int LIS(vector<int> data)
{
int length = data.size(),i,j,res = 1;
if(length == 0)return 0;
vector<int> dp(length,0);
dp[0] = data[0];
for(i = 1; i < length;++i)
{
int left = 0,right = res-1;
while(left <= right)//寻找以data[i]结尾的最长递增子序列
{
int mid = left + ((right - left) >> 1);
if(dp[mid] < data[i])left = mid + 1;
else right = mid - 1;
}
dp[left] = data[i]; //表示data[i]应该放在长度为left+1的子序列的最后一个元素上
if(left >= res)res = left+1;//更新最大长度
}
return res;
}
int main()
{
int n,i;
while(cin >> n)
{
vector<int> data(n);
for(i = 0; i < n;++i)cin >> data[i];
cout << LIS(data) << endl;
}
return 0;
}