首页 > 代码库 > 最大不降子序列
最大不降子序列
解法1(二分法:o(n*log2(n))):
#include <stdio.h>
#include <iostream>
#define MAXN 10000
using namespace std;
int a[MAXN], low[MAXN];
int main(void)
{
int n;
while(cin >> n)
{
low[1]=a[1];
int now=1;
for(int i=1; i<=n; i++)
cin >> a[i];
for(int i=2; i<=n; i++)
{
if(a[i]>low[now]) low[++now]=a[i];
else
{
int pos=lower_bound(low, low+now, a[i]) - low;
low[pos]=a[i];
}
}
cout << now << endl;
}
return 0;
}
解法2(二分法队列实现:o(n*long2(n))):
#include <stdio.h>
#include <iostream>
#include <string.h>
#define MAXN 1000000
using namespace std;
int main(void)
{
int n;
while(cin >> n)
{
int stack[MAXN];
int top=0;
stack[0]=-1;
for(int i=1; i<=n; i++)
{
int temp;
cin >> temp;
if(temp>stack[top]) stack[++top]=temp;
else
{
int pos=lower_bound(stack, stack+top, temp)-stack;
stack[pos]=temp;
}
}
cout << top << endl;
}
return 0;
}
解法3(o(n*n)):
#include <stdio.h>
#include <iostream>
#define MAXN 10000+10
using namespace std;
int main(void)
{
int n;
while(cin >> n)
{
int a[MAXN], alen[MAXN], maxlen=1;
for(int i=1; i<=n; i++)
alen[i]=1;
for(int i=1; i<=n; i++)
cin >> a[i];
for(int i=2; i<=n; i++)
{
int max=0;
for(int j=1; j<=i-1; j++)
if(a[j]<a[i] && max<alen[j]) max=alen[j];
alen[i]=max+1;
if(alen[i]>maxlen) maxlen=alen[i];
}
cout << maxlen << endl;
}
return 0;
}
方法4(dp(o(n*n))):
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#define MAXN 100
using namespace std;
int main(void)
{
int n;
while(cin >> n)
{
int a[MAXN], low[MAXN];
memset(low, 0, sizeof(low));
for(int i=0; i<n; i++)
cin >> a[i];
for(int i=0; i<n; i++)
{
for(int j=i+1; j<n; j++)
{
if(a[j]>a[i])
low[j]++;
}
}
sort(low, low+n);
cout << low[n-1];
}
return 0;
}
最大不降子序列