码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-05-16 01:27:53      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

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

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

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

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

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn = 1010;
 7 int m, n, lim;
 8 int dp[maxn][maxn];
 9 bool solve(int h)
10 {
11    
12     for(int i = h; i <= n; i++)
13     {
14         for(int j = h; j <= m; j++)
15         {
16             if(dp[i][j]-dp[i-h][j]-dp[i][j-h]+dp[i-h][j-h] > lim) continue;
17             return true;
18         }
19     }
20     return false;
21 }
22 int main()
23 {
24     int T; scanf("%d", &T);
25     while(T--)
26     {
27         scanf("%d%d%d", &n, &m, &lim);
28         memset(dp, 0, sizeof(dp));
29         for(int i = 1; i <= n; i++)
30         {
31             int tmp = 0;
32             for(int j = 1; j <= m; j++)
33             {
34                 int x; scanf("%d", &x);
35                 tmp += x;
36                 dp[i][j] = dp[i-1][j]+tmp;
37             }
38         }
39 
40         int H = min(n, m);
41         int L = 0, R = H;
42         int M;
43         while(L < R)
44         {
45             M = L+(R-L)/2;
46             if(M == L) M++; //避免死循环
47             if(solve(M)) L = M;
48             else R = M-1;
49         }
50         cout << L*L << endl;
51     }
52     return 0;
53 }

 

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

标签:

原文地址:http://www.cnblogs.com/LLGemini/p/4507215.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!