您的位置:首页 > 其它

【二分查找最优解】FZU 2056 最大正方形

2015-05-16 00:23 183 查看

题意:现在有一个n*m的矩阵A,在A中找一个H*H的正方形,使得其面积最大且该正方形元素的和不大于 limit。

分析:开始以为是DP或者二维RMQ,其实用二分就可以做出来;

    在输入时构造元素和矩阵dp[][](即dp[i][j]为从(1,1)到(i,j)的矩形范围元素和);再在(0,min(m,n))范围内二分查找满足条件的最优解H;计算正方形内元素和的方法要掌握;

   注意二分时要避免出现L==M而死循环的情况。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn = 1010;
int m, n, lim;
int dp[maxn][maxn];
bool solve(int h)
{

for(int i = h; i <= n; i++)
{
for(int j = h; j <= m; j++)
{
if(dp[i][j]-dp[i-h][j]-dp[i][j-h]+dp[i-h][j-h] > lim) continue;
return true;
}
}
return false;
}
int main()
{
int T; scanf("%d", &T);
while(T--)
{
scanf("%d%d%d", &n, &m, &lim);
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i++)
{
int tmp = 0;
for(int j = 1; j <= m; j++)
{
int x; scanf("%d", &x);
tmp += x;
dp[i][j] = dp[i-1][j]+tmp;
}
}

int H = min(n, m);
int L = 0, R = H;
int M;
while(L < R)
{
M = L+(R-L)/2;
if(M == L) M++; //避免死循环
if(solve(M)) L = M;
else R = M-1;
}
cout << L*L << endl;
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: