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


    题意:现在有一个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 }
  • 相关阅读:
    mongodb将mysql数据导入
    mongodb增删改查操作
    mongdb安装
    Python获取两个文件的交集、并集、差集
    java回调函数详解
    java线程锁之synchronized
    mysql知识点汇集
    Springboot2.0实现URL拦截
    idea将springboot打包成jar或者war
    leetcode1128
  • 原文地址:https://www.cnblogs.com/LLGemini/p/4507215.html
Copyright © 2020-2023  润新知