奶牛浴场——最大子矩形问题

http://codewaysky.sinaapp.com/problem.php?id=1057提交这题的OJ比较少,可以在这里提交

 

根据王知昆的论文里说的,解决这种问题通常有两种方法。这里我用的第二种方法。

什么都不懂的,先看论文http://wenku.baidu.com/view/728cd5126edb6f1aff001fbb.html

 

具体的没啥好说的,根据论文里说的实现以下就是了,详细注释看code

 

View Code
  1 #include<iostream>
  2 #include<string>
  3 #include<stdio.h>
  4 #include<memory.h>
  5 #include<algorithm>
  6 using namespace std;
  7 
  8 int n,m;
  9 int v[5010][5010],h[5010],l[5010],r[5010];
 10 int x[5010],y[5010],lenx,leny;
 11 int a[5010],b[5010];
 12 
 13 int findx(int c)
 14 {
 15     int l=0,r=lenx-1;
 16     int mid;
 17     while(l<=r)
 18     {
 19         mid=(l+r)/2;
 20         if(x[mid]==c)
 21             return mid;
 22         if(x[mid]>c)
 23             r=mid-1;
 24         else
 25             l=mid+1;
 26     }
 27 }
 28 
 29 int findy(int c)
 30 {
 31     int l=0,r=leny-1;
 32     int mid;
 33     while(l<=r)
 34     {
 35         mid=(l+r)/2;
 36         if(y[mid]==c)
 37             return mid;
 38         if(y[mid]>c)
 39             r=mid-1;
 40         else
 41             l=mid+1;
 42     }
 43 }
 44 
 45 int main()
 46 {
 47     int i,j,p,aa,bb;
 48     //freopen("D:\\in.txt","r",stdin);
 49     while(scanf("%d%d",&n,&m)==2)
 50     {
 51         scanf("%d",&p);
 52         lenx=leny=0;
 53         for(i=0;i<p;i++)
 54         {
 55             scanf("%d%d",&a[i],&b[i]);
 56             x[lenx++]=a[i];
 57             y[leny++]=b[i];
 58         }
 59         //******************************//离散化
 60         x[lenx++]=0;y[leny++]=0;
 61         x[lenx++]=n;y[leny++]=m;
 62         sort(x,x+lenx);
 63         sort(y,y+leny);
 64         for(j=1,i=1;i<lenx;i++)
 65         {
 66             if(x[i]!=x[i-1])
 67                 x[j++]=x[i];
 68         }
 69         lenx=j;
 70         for(j=1,i=1;i<leny;i++)
 71         {
 72             if(y[i]!=y[i-1])
 73                 y[j++]=y[i];
 74         }
 75         leny=j;
 76         //*******************************//
 77         memset(v,0,sizeof(v));
 78         for(i=0;i<p;i++)
 79         {
 80             aa=findx(a[i]);
 81             bb=findy(b[i]);
 82             v[aa][bb]=1; //标记障碍点
 83         }
 84         int lm,rm,ans=0,temp;
 85         for(i=0;i<leny;i++)
 86         {
 87             l[i]=0;r[i]=m;h[i]=0;
 88         }
 89         for(i=1;i<lenx;i++)
 90         {
 91             lm=0;
 92             for(j=0;j<leny;j++)
 93             {
 94                 if(!v[i-1][j]) //如果上一个不是障碍点
 95                 {
 96                     h[j]=h[j]+x[i]-x[i-1]; //高度累加
 97                     if(lm>l[j]) //l[i][j]=max(l[i-1][j] , (i-1,j)左边第一个障碍点的位置)
 98                         l[j]=lm;
 99                 }
100                 else //如果上一个点是障碍点
101                 {
102                     h[j]=x[i]-x[i-1]; //高度重新计算
103                     l[j]=0;
104                     r[j]=m;
105                     lm=y[j]; //更新(i-1,j)左边第一个障碍点的位置
106                 }
107             }
108             rm=m;
109             for(j=leny-1;j>=0;j--)
110             {
111                 if(r[j]>rm) //r[i][j]=min(r[i-1][j] , (i-1,j)右边第一个障碍点的位置)
112                     r[j]=rm;
113                 temp=h[j]*(r[j]-l[j]);
114                 if(temp>ans) //计算最优解
115                     ans=temp;
116                 if(v[i-1][j]) //如果该点是障碍点,更新(i-1,j)右边第一个障碍点的位置
117                     rm=y[j];
118             }
119         }
120         for(i=1;i<lenx;i++) //计算相邻y坐标之间的面积
121         {
122             temp=m*(x[i]-x[i-1]);
123             if(temp>ans)
124                 ans=temp;
125         }
126         printf("%d\n",ans);
127     }
128     return 0;
129 }
posted @ 2012-09-30 13:59  Accept  阅读(1219)  评论(0编辑  收藏  举报