题目来源:http://codeforces.com/problemset/problem/333/D
题意就是找一个矩形,ans是四个顶点的最小值,求ans的最大值
想了好久的DP,没想到 有空再想想
最后是二分加搜索
说不清 看代码比较好理解
就是把每一列大于mid的位置记录 然后找下一列是否会重叠,如果重叠则证明还存在更优的 然后二分
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN 1005
using namespace std;
int n,m,maxv,ans;
int a[MAXN][MAXN];
bool vis[MAXN][MAXN];
int max(int A,int B)
{
if(A>B)
return A;
else
return B;
}
bool find(int mid)
{
memset(vis,false,sizeof(vis));
int set[MAXN];
for(int i=0;i<n;i++)
{
int sum=0;
for(int j=0;j<m;j++)
{
if(a[i][j]>=mid)
{
set[sum]=j;
sum++;
}
}
for(int j=0;j<sum-1;j++)
{
for(int k=j+1;k<sum;k++)
{
if(vis[set[j]][set[k]])
{
return true;
}
vis[set[j]][set[k]]=true;
}
}
}
return false;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
maxv=0;ans=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&a[i][j]);
maxv=max(maxv,a[i][j]);
}
}
int l=0;
int r=maxv;
while(l<=r)
{
int mid=(l+r)/2;
if(find(mid))
{
l=mid+1;
ans=max(ans,mid);
}
else
{
r=mid-1;
}
}
printf("%d\n",ans);
}
return 0;
}