偏序关系和Dilworth定理(poj 1548)

来源:互联网 发布:数据分析师 挂靠 编辑:程序博客网 时间:2024/06/07 16:20

偏序关系

集合 P上的关系 R 称为 P上的偏序关系,当且仅当 R是自反的、反对称的和传递的。

Ⅰ  自反性:对任意xA,有xRx
Ⅱ 反对称性(即反对称关系):对任意x,yA,若xRy,且yRx,则x=y
Ⅲ 传递性:对任意x, y,zA,若xRy,且yRz,则xRz

则称R为A上的偏序关系,通常记作≼

哈斯图

对于给定的<A,≼>,常利用盖住关系作哈斯图,其作图规则:

Ⅰ用圆圈表示元素

Ⅱ若x≼y , 且(x != y) ,则把代表y的小圆圈画在代表x的小圆圈之上

Ⅲ 若x ,y ∈COVA ,  则x,y用直线连接。其中  COVA = { <x ,y> | x,yA  , y 盖住 x  ,即不存在 z  st  x ≼ z , z ≼ y };


链 :

设<A,≼>是一个偏序集 , 在A的一个子集中, 如果每两个元素都是有关系的,则称这个子集是链 ;

反链 :

在A的一个子集中, 如果每两个元素都是没有关系的,则称这个子集是反链

链和反链可以从哈斯图中直观看出。

相关定理

定理1 令(X,≤)是一个有限偏序集,并令r是其最大链的大小。则X可以被划分成r个但不能再少的反链。

 Dilworth定理:
定理2 令(X,≤)是一个有限偏序集,并令m是反链的最大的大小。则X可以被划分成m个但不能再少的链。


链就是从纵向的角度看 哈斯图 ,反链是从横向的角度看 哈斯图。

定理1,就是至少有r行构成反链关系。

定理2,就是至少有m列构成链关系。

Dilworth定理应用

POJ 1548

题意 :给出一个矩阵,从最左上点到最右下点走,并且只能往下走和往右走,在矩阵中的一些格子中有含有一个‘G’,问最少从最左上到最右下走多少次,能把所有的G都走到

求一次非往下走和往右走的最长子序列

#include <stdio.h>#include <algorithm>#include <string>#include <string.h>#include <vector>#include <bits/stdc++.h>using namespace std ;const int maxn = 1005 ;int d[maxn] ;struct litter{    int x , y ;}; bool cmp (const litter &a , const litter &b){    if(a.x == b.x) return a.y < b.y ;     else  return a.x < b.x ;} bool operator > (const litter &a , const litter &b){      return !(a.x <= b.x && a.y <= b.y) ;}vector <litter> p ;int main(){  // freopen("a.txt" , "r" , stdin) ;   litter t ;   int sum ;   while( scanf("%d%d" , &t.x , &t.y) != EOF)   {       if(t.x == -1 && t.y == -1) break ;       p.clear() ;       p.push_back(t) ;       while(scanf("%d%d" , &t.x , &t.y), t.x && t.y)       {           p.push_back(t) ;       }       sort(p.begin(), p.end() , cmp) ;       sum = -1 ;       for(int i = 0 ; i < p.size() ; i ++)       {<span><span class="comment">  //动态规划求解p数组的最长降序子序列的长度</span><span> </span></span>           d[i] = 1 ;           for(int j = 0 ; j < i ; j ++)           {               if(d[j] + 1 > d[i] && p[j] > p[i])                 d[i] = d[j] + 1 ;           }           sum = max(sum , d[i]) ;       }       printf("%d\n" , sum) ;   }   return 0 ;}




0 0
原创粉丝点击