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 }