【二分查找最优解】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; }
相关文章推荐
- FZU 2056 最大正方形
- FZU 2056 最大正方形
- fzu 2056(二分查找)
- 【FZU】Problem 2056 最大正方形
- 算法整理-二分查找列表最大值
- POJ_2112_Optimal Milking( 二分查找 + Floyd + 最大流EK )
- poj 2002 Squares 判断一些点能组成多少个正方形 二分查找
- C语言【顺序表】冒泡排序,一次选出最大最小的数据,二分查找,初始化顺序表
- 8.3.5(最大值最小化_二分查找)
- 0 1 矩阵查找最大正方形
- 动态规划和二分查找的方式 求最大递增子序列
- hdoj 3081 Marriage Match II 【二分查找+ 最大流 + 并查集 or floyd】【二分图求最大匹配 + 并查集 or floyd】
- ZOJ 3640--Missile【二分查找 && 最大流dinic && 经典建图】
- Java数组遍历、求最大值、选择排序、冒泡排序、二分查找
- [dp][二分答案]最大正方形
- FZU-1881-Problem 1881 三角形问题,打表二分查找~~
- 二分算法(如果要查找的数不存在返回比该值小的最大值)
- [swustoj 1092] 二分查找的最大次数
- 【单调队列+二分查找】bzoj 1012: [JSOI2008]最大数maxnumber
- POJ 2289--Jamie's Contact Groups【二分图多重匹配问题 &&二分查找最大值的最小化 && 最大流求解】