【openjudge 1759】最长上升子序列(dp)
【题解】【O(n²)&O(nlogn)】
朴素最长上升子序列O(n²):
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[10010],n,a[10010];
int main()
{
int i,j;
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
f[i]=1;
for (i=2;i<=n;i++)
for (j=1;j<i;j++)
if (a[j]<a[i]&&f[j]+1>f[i])
f[i]=f[j]+1;
for (i=2;i<=n;i++)
f[i]=max(f[i-1],f[i]);
printf("%d",f[n]);
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int tree[100010],a[10010],num[10010],n,ans;
inline int lowbit(int x)
{
return (x&(-x));
}
inline void add(int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i))
if(val>tree[i]) tree[i]=val;
}
inline int ask(int x)
{
int sum=0;
for(int i=x;i>0;i-=lowbit(i))
if(tree[i]>sum) sum=tree[i];
return sum;
}
int main()
{
int i,j;
scanf("%d",&n);
for(i=1;i<=n;++i)scanf("%d",&a[i]),num[i]=a[i];
sort(num+1,num+n+1);
int m=unique(num+1,num+n+1)-num-1;
for(i=1;i<=n;++i)
{
a[i]=lower_bound(num+1,num+m+1,a[i])-num;
int tmp=ask(a[i])+1;
if(tmp>ans) ans=tmp;
add(a[i]+1,tmp);
}
printf("%d\n",ans);
return 0;
}
既然无能更改,又何必枉自寻烦忧