最大(优)子矩阵问题合集 -- 持续更新
2017-09-03 09:27
239 查看
1.引进:
最近打算撸最大子矩阵这类问题,以后所有有关最大最优子矩阵的题目,都会补充道这里面。嘛,这类问题还是挺有用处的,可以当做打牢基础的一些思维题目或者练习代码能力的题目来看,如有不对之处还请读者指出。哈哈
2.题目参考:
奶牛浴场问题(极大化思想)
参考博客:这道题最重要的还是要想到每次都计算的极大有效子矩形这一点就可以优化成n^2了,其实自己多想想还是挺好理解的。
我起初这句话半天没看懂~,画图又想了很久之后终于解决了:
1.类似的,需要相应地修改上边界。以此类推,如果这个点是在当前点(确定左边界的点)上方,则修改上边界;如果在下方,则修改下边界;如果处在同一行,则可中止搜索(因为后面的矩形面积都是0了)。 一开始感觉有问题~
~ ~ 如果以此行为上边界或者写边界不可以吗???
2.对于这种情况,可以用类似的方法从右到左扫描每一个点作为右边界的情况。
想想这两句话还是挺重要的,如果有哪里不懂可以指出来,我会的话可以给大家解答。
上代码:
#include<cstdio> #include<cstdlib> #define N 5010 #include<cstring> int comp(const void*a,const void*b)//用来做比较的函数。 { return *(int*)a-*(int*)b; } int Fcomp(const void*a,const void*b)//用来做比较的函数。 { return *(int*)b-*(int*)a; } int L, W; int n; int miny, maxy; int maxS; int thisS; int a [2]; int b [2]; int temp [2]; int main() { // freopen("in.txt", "r", stdin); memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); scanf("%d%d", &L, &W); scanf("%d", &n); miny = 0; maxy = W; maxS = -1; thisS = 0; for(int i = 0; i < n; i ++) { scanf("%d%d", &a[i][0], &a[i][1]); b[i][0] = a[i][0]; b[i][1] = a[i][1]; } a [0] = L; a [1] = 0; a[n + 1][0] = 0; a[n + 1][1] = 0; a[n + 2][0] = 0; a[n + 2][1] = W; a[n + 3][0] = L; a[n + 3][1] = W; b [0] = L; b [1] = 0; b[n + 1][0] = 0; b[n + 1][1] = 0; b[n + 2][0] = 0; b[n + 2][1] = W; b[n + 3][0] = L; b[n + 3][1] = W; qsort(a[0], n + 4, sizeof(a[0]), comp); // for(int i = 0; i < n + 4; i ++) // printf("%d %d\n", a[i][0], a[i][1]); // printf("\n"); for(int i = 0; i < n + 4; i ++) { miny = 0; maxy = W; for(int j = i + 1; j < n + 4; j ++) { thisS = (maxy - miny) * (a[j][0] - a[i][0]); // printf("+%d ", thisS); if(thisS > maxS) maxS = thisS; if(a[j][1] >= a[i][1] && a[j][1] <= maxy) maxy = a[j][1]; if(a[j][1] <= a[i][1] && a[j][1] >= miny) miny = a[j][1]; if(a[j][1] == a[i][1]) break; } } for(int i = 0; i < n + 4; i ++) { temp[i][0] = b[i][0]; b[i][0] = b[i][1]; b[i][1] = temp[i][0]; } qsort(b[0], n + 4, sizeof(b[0]), Fcomp); for(int i = 0; i < n + 4; i ++) { temp[i][0] = b[i][0]; b[i][0] = b[i][1]; b[i][1] = temp[i][0]; } // for(int i = 0; i <= n; i ++) // { // printf("%d %d\n", b[i][0], b[i][1]); // } for(int i = 0; i < n + 4; i ++) //整个矩形的左右边界为左右边界 { thisS = L * (b[i][1] - b[i + 1][1]); // printf("%d*** ", thisS); if(thisS > maxS) maxS = thisS; } qsort(a[0], n + 4, sizeof(a[0]), comp); int ttx = 0; int tty = W; for(int i = n + 3; i >= 0; i --) { ttx = 0; tty = W; for(int j = i - 1; j >= 0; j --) { thisS = (tty - ttx) * (a[i][0] - a[j][0]); // printf("%d^%d^%d\n", tty - ttx, a[i][0] - a[j][0], thisS); if(thisS > maxS) maxS = thisS; if(a[j][1] > a[i][1] && a[j][1] < tty) tty = a[j][1]; if(a[j][1] < a[i][1] && a[j][1] > ttx) ttx = a[j][1]; if(a[j][1] == a[i][1]) break; } } printf("%d", maxS); }
一个很有意思的博客地址,球球好玩,代码简洁。
悬线法
待更新。。。相关文章推荐
- C++编程问题合集(持续更新中...)
- android 开发中常见问题合集(持续更新)
- mongoDB问题合集(持续更新)
- 学习工作中遇到的问题合集------持续更新
- mysql关于日期的问题(合集,持续更新中:2018.03.26)
- 那些年我们装过的数据库---盘点sqlserver2008安装时遇到的各种的问题(持续更新中)
- destoon 建站问题解决,持续更新....
- java2word 使用中问题集锦(持续更新中。。。)
- openstack 问题集锦 -- 持续更新中
- [Java]常见算法问题(持续学习,更新)
- iOS UI、Xcode、调试、代码等常见问题总汇(持续更新中)
- SQL语句常见问题的总结(持续更新)
- myeclipse中编写小java项目遇到的一些问题(持续更新)
- kafka 常用命令与问题(持续更新)
- “Windows + VirtualBox Ubuntu” 问题与解决笔记【持续更新】
- IntellijIDEA 遇到的各种问题(持续更新---)
- 单片机控制SPI协议时钟芯片DS1302之模块化编程及待解决的问题(持续更新中)
- Android开发小问题tips---持续更新中~
- iOS面试问题全面梳理 --持续更新
- 【常见问题汇总--持续更新】Keystone常见问题