Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 38934 | Accepted: 17094 |
Description
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
Input
Output
Sample Input
7 1 7 3 5 9 4 8
Sample Output
4
題意:長度爲n的數列,求最長遞增子序列的長度。
法一:動態規劃,時間複雜度O(N²):
dp[i]表示以第i個爲結尾的數列的最長子序列長度,等於該數之前的最長子序列(該數大於子序列的最大數)的長度加一。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[1005],dp[1005];
int main()
{
int n,maxn,ans;
while(scanf("%d",&n) != EOF) {
ans = 0;
for(int i = 0; i < n; i++) {
scanf("%d",&a[i]);
maxn = 0;
for(int j = 0; j < i; j++)
{
if(dp[j] > maxn && a[i] > a[j])
maxn = dp[j];
}
dp[i] = maxn + 1;
ans = max(ans, dp[i]);
}
printf("%d\n",ans);
}
}
法二:時間複雜度O(NlogN):
每輸入一個值,用二分查找找到它的位置,頂替該位置的數,保持數列遞增。最後得到的數列長度就是最長子序列長度,但不是最長子序列。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[1005],n,num,ans,p;
int erfen(int num, int a[])
{
int l = 0, r = n, mid;
while(l < r) {
mid = (l + r) >> 1;
if(num <= a[mid])
r = mid;
else if(num > a[mid])
l = mid + 1;
}
return r;
}
int main()
{
while(scanf("%d",&n) != EOF) {
for(int i = 0; i < 1005; i++)
a[i] = 10005;
for(int i = 0; i < n; i++) {
scanf("%d",&num);
p = erfen(num,a);
if(a[p] == 10005)
ans ++;
a[p] = num;
}
printf("%d\n",ans);
}
}