POJ1065+POJ3636(偏序定理)

说到偏序集,在离散里的定义是:

      设R为非空集合A上的关系,如果R是自反的、反对称的和传递的,则称R为A上的偏序关系,简称偏序,记作≤。

偏序是在集合X上的二元关系≤(这只是个抽象符号,不是“小于或等于”),它满足自反性、反对称性和传递性。即,对于X中的任意元素a,b和c,有:
自反性:a≤a;
反对称性:如果a≤b且b≤a,则有a=b;
传递性:如果a≤b且b≤c,则a≤c 。

带有偏序关系的集合称为偏序集。
令(X,≤)是一个偏序集,对于集合中的两个元素a、b,如果有a≤b或者b≤a,则称a和b是可比的,否则a和b不可比。
在X中,对于元素a,如果任意元素b,由b≤a得出b=a,则称a为极小元。

一个反链A是X的一个子集,它的任意两个元素都不能进行比较。
一个链C是X的一个子集,它的任意两个元素都可比。

任何集合A上的恒等关系,集合的幂集P(A)上的包含关系,实数集上的小于等于关系,正整数集上的整除关系等都是偏序关系。

那么现在,我们重点利用集合的包含关系来解决poj1065、poj3636这两题。

POJ1065 题意:有n个木棒,分别不同的长度和不同的重量,一个机器需要处理这些木棒,如果第i+1个木棒的重量和长度都>=第i个处理的木棒,那么将不会耗费时间,否则需要增加一个单位的时间,问最少需要多少时间处理完(包括机器启动的时间)。

POJ3636 题意:套娃娃,只有当 w1 < w2 && h1 < h2 时才能将娃娃(w1,h1)套在娃娃(w2,h2)里面,问最少需要多少嵌套的娃娃。

算法:二者区别在于前者是大于等于关系,而后者必须是大于的。这就导致了二者排序的方式不一样,第一个参数都是从小到大排,但是第二个参数就有所区别了。前者要求是包含  =的,所以第2个参数也是从小到大排;而后者则不包含 = 所以要从大到小排 。因为w升序,h降序可以保证w相等时,一定不会出现覆盖的情形。

POJ1065 代码:

ExpandedBlockStart.gif View Code
 1  #include < stdio.h >
 2  #include < algorithm >
 3  using   namespace  std;
 4  #define  Max 5005
 5  struct  node{
 6       int  l,w;
 7  }n[Max];
 8 
 9  int  an[Max];
10  bool  cmp(node x,node y)
11  {
12       if (x.w == y.w)  return  x.l < y.l;
13       return  x.w < y.w;
14  }
15 
16  int  main()
17  {
18       int  t,m,i,j;
19      scanf( " %d " , & t);
20       while (t -- )
21      {
22          scanf( " %d " , & m);
23           for (i = 0 ;i < m;i ++ )
24              scanf( " %d%d " , & n[i].l, & n[i].w);
25          sort(n,n + m,cmp);
26           int  num = 0 ;
27           for (i = 0 ;i < m;i ++ )
28          {
29               int  flag = 0 ;
30               for (j = 0 ;j < num;j ++ )
31                 if (n[i].l >= an[j])
32                {
33                    an[j] = n[i].l;
34                    flag = 1 ;
35                     break ;
36                }
37               if ( ! flag)     an[num ++ ] = n[i].l;
38          }
39          printf( " %d\n " ,num);
40      }
41       return   0 ;
42  }

POJ3636 代码:

ExpandedBlockStart.gif View Code
 1  #include < stdio.h >
 2  #include < algorithm >
 3  using   namespace  std;
 4  #define  Max 20001
 5  struct  D{
 6       int  w,h;
 7  }d[Max];
 8  D dd[Max];
 9 
10  bool  cmp(D x,D y) // w升序,h降序可以保证w相等时,一定不会出现覆盖的情形。
11  {
12       if (x.w == y.w)  return  x.h > y.h; 
13       return  x.w < y.w; 
14  }
15  int  main()
16  {
17       int  n,i,j,m;
18      scanf( " %d " , & n);
19       while (n -- )
20      {
21           int  result = 0 ;
22          scanf( " %d " , & m);
23           for (i = 0 ;i < m;i ++ )
24              scanf( " %d%d " , & d[i].w, & d[i].h);
25          sort(d,d + m,cmp);
26           for (i = 0 ;i < m;i ++ )
27          {
28               int  flag = 0 ;
29               for (j = 0 ;j < result;j ++ )
30                   if (d[i].w > dd[j].w && d[i].h > dd[j].h)
31                  {
32                      dd[j] = d[i];
33                      flag = 1 ;
34                       break ;
35                  }
36                   if ( ! flag) dd[result ++ ] = d[i];
37          }
38          printf( " %d\n " ,result);
39         }
40       return   0 ;
41  }

 


 

转载于:https://www.cnblogs.com/yueshuqiao/archive/2011/08/21/2147782.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值