洛谷 P1233 木棍加工 题解

题面

Dilworth定理在数学理论中的序理论与组合数学中,Dilworth定理根据序列划分的最小数量的链描述了任何有限偏序集的宽度。

反链是一种偏序集,其任意两个元素不可比;而链则是一种任意两个元素可比的偏序集。Dilworth定理说明,存在一个反链A与一个将序列划分为链族P的划分,使得划分中链的数量等于集合A的基数。当存在这种情况时,对任何至多能包含来自P中每一个成员一个元素的反链,A一定是此序列中的最大反链。同样地,对于任何最少包含A中的每一个元素的一个链的划分,P也一定是序列可以划分出的最小链族。偏序集的宽度被定义为A与P的共同大小。

另一种Dilworth定理的等价表述是:在有穷偏序集中,任何反链最大元素数目等于任何将集合到链的划分中链的最小数目。一个关于无限偏序集的理论指出,在此种情况下,一个偏序集具有有限的宽度w,当且仅当它可以划分为最少w条链。

对于dilworth定理,我的理解就是:
在一个序列中 最长下降子序列的个数(下降子序列的最小划分)就等于其最长不下降子序列的长度
#include 
#pragma GCC optimize(2)
using namespace std;
struct haha{
    int a;
    int b;
}lala[2000010];
int n;
inline bool cmp(haha x,haha y)
{
    if(x.a==y.a) return x.b>y.b;
    return x.a>y.a;
}
int c[2000010];
inline int lowbit(register int x)
{
    return x&(-x);
}
int maxn;
inline int ask(register int x)
{
    register int res=0;
    while(x>0){
        if(res<c[x]){
            res=c[x];
        }
        x-=lowbit(x);
    }
    return res;
}
inline void add(register int x,register int v)
{
    while(x<=maxn){
        c[x]=max(c[x],v);
        x+=lowbit(x);
    }
}
int main()
{    
    cin>>n;
    for(register int i=1;i<=n;i++){
        scanf("%d%d",&lala[i].a,&lala[i].b);
        maxn=max(maxn,lala[i].b);
    }
    sort(lala+1,lala+1+n,cmp);
    register int ans=0;
    for(register int i=1;i<=n;i++){
        register int j=ask(lala[i].b)+1;
        ans=max(ans,j);
        add(lala[i].b+1,j);
    }
    cout<<ans;
}

 

转载于:https://www.cnblogs.com/kamimxr/p/11522593.html

你可能感兴趣的:(洛谷 P1233 木棍加工 题解)