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

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 }

你可能感兴趣的:(问题)