题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541

此前有一道更简单的二维偏序问题:hdu1541(Stars)

分析:同样是偏序问题,使用树状数组可以降低复杂度到nlogn

代码1:n^2的dp

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int n=0,h[maxn],dp[maxn],fp[maxn];
int main()
{
    while(~scanf("%d",&h[++n]));
    n--;
    /*
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&h[i]);
    */
    for(int i=1;i<=n;i++) dp[i]=fp[i]=1;
    for(int i=1;i<n;i++)
        for(int j=n;j>=1+i;j--)
        {
            if(h[j]<=h[i]) dp[j]=max(dp[j],dp[i]+1);
            else fp[j]=max(fp[j],fp[i]+1);
        }
    int ans1=0,ans2=0;
    for(int i=1;i<=n;i++) 
    {
        ans1=max(ans1,dp[i]);
        ans2=max(ans2,fp[i]);
    }
    printf("%d\n%d",ans1,ans2);
    return 0;
}

代码2:上树状数组

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 2;
const int range = 50002;
int c[range],h[maxn];
int lowbit(int x)
{
    return x&-x;
}
void add(int x,int y)
{
    while(x<=range)
    {
        c[x]=max(c[x],y);   x+=lowbit(x);
    }
}
int query(int x)
{
    int ans=0;
    while(x)
    {
        an***ax(ans,c[x]);  x-=lowbit(x);
    }
    return ans;
}
int main()
{
    int a=0,b=0,n=0;
    while(scanf("%d",&h[++n])!=EOF);
    n--;
	memset(c,0,sizeof(c));
    for(int i=n;i>=1;i--)
    {
        int x=query(h[i])+1;
        add(h[i],x);
        a=max(a,x);
    }
    memset(c,0,sizeof(c));
    for(int i=1;i<=n;i++)
    {
        int x=query(h[i]-1)+1;
        add(h[i],x);
        b=max(b,x);
    }
    printf("%d\n%d",a,b);
    return 0;
}