ACM算法:悬线法
来源:互联网 发布:linux 抓包文件 导出 编辑:程序博客网 时间:2024/06/05 08:07
悬线法的用途:针对求给定矩阵中满足某条件的极大矩阵,比如“面积最大的长方形、正方形”“周长最长的矩形等等”。可以满足在
时间复杂度为O(M*N)的要求,比一般的枚举高效的多,也易于理解。
悬线法思路:悬线法,悬线的定义,就是一条竖线,这条竖线要满足上端点在整个矩形上边界或者是一个障碍点。然后以这条悬线
进行左右移动,直到移至障碍点或者是矩阵边界,进而确定这条悬线所在的极大矩阵。也就是说,我们要针对矩阵中每个点进行求极
大矩阵的操作,所以我们需要Left[]数组存每个点能到达的最右位置,Right[]数组存放每个点能到达的最左位置,Up[]数组位置。
设置好这些数组之后,我们开始遍历矩阵中的每个点ves[i,j],把每个点和上一个点(ves[i-1][j])的Left和Right进行比较,分别取最大和
最小,Up则是上一个点的Up+1,进而求出面积进行比较。所以我们可以得到相关的递推公式。
递推公式:Up:Up[i][j] = Up[i-1][j] + 1
Right:min(Right[i][j],RIght[i-1],[j])
Left::max(Left[i][j],Left[i-1][j])
在这里推荐一篇国家队的论文《极大化思想解决最大子矩阵问题》
http://blog.csdn.net/clover_hxy/article/details/50532289?locationNum=1&fps=1
这里全面讲解了极大化矩阵的思想,只要能看透,我相信对于悬线法的理解肯定会更加深入。只是没有例题,所以你进行理解后再
倒回来理解我的例题,印象会更加深刻。
例题解析:
题目:棋盘制作
Input
3 31 0 10 1 01 0 0
46
这是中文题,大家都看得懂,我这就不解释什么了,直接上代码
#include <iostream>#include <algorithm>using namespace std;const int Max = 2005;int ves[Max][Max], up[Max][Max], Left[Max][Max], Right[Max][Max];int temp1 = 1, temp2 = 1;int main(void){ios::sync_with_stdio(false);int N, M;cin >> N >> M;for(int i = 1; i <= N; i++)for (int j = 1; j <= M; j++) {cin >> ves[i][j];Left[i][j] = Right[i][j] = j;//初始化Right和Left,使他们值为点所在纵坐标up[i][j] = 1;//初始化up使其值为1}for (int i = 1; i <= N; i++)for (int j = 2; j <= M; j++)if (ves[i][j] == 1 - ves[i][j - 1])//判断相邻两个数是否不同Left[i][j] = Left[i][j - 1];//是,则for (int i = 1; i <= N; i++)for (int j = M - 1; j > 0; j--)if (ves[i][j] == 1 - ves[i][j + 1])Right[i][j] = Right[i][j + 1];for(int i = 1;i <= N; i++)for (int j = 1; j <= M; j++) {if (i > 1 && ves[i][j] == 1 - ves[i - 1][j]) {//递推公式Left[i][j] = max(Left[i][j], Left[i - 1][j]);Right[i][j] = min(Right[i][j], Right[i - 1][j]);up[i][j] = up[i - 1][j] + 1;}int A_instance = Right[i][j] - Left[i][j] + 1;//计算长度int B_instance = min(A_instance, up[i][j]);//算出长宽中较小的边,以计算正方形temp1 = max(temp1, B_instance * B_instance);//正方形面积temp2 = max(temp2, A_instance * up[i][j]);//长方形面积}cout << temp1 << endl << temp2 << endl;}
总结:悬线法也是针对一类问题——求极大矩阵的问题,学会之后又将是解决一类问题的利器,而起思路非常清晰,易于理解。
只是有时候变式比较多,需要多加练习进行熟练。
- ACM算法:悬线法
- ACM 算法
- ACM算法
- ACM算法
- 算法:ACM算法学习
- ACM+算法集--常用ACM算法
- ACM 算法题目解
- ACM算法集1
- ACM算法集2
- ACM算法集3
- ACM算法集4
- ACM算法集5
- ACM程序&算法
- acm常用算法
- acm算法分类
- ACM算法书籍
- acm常用算法
- acm 常用算法
- 类与对象和方法
- Android 反编译后修改 APK 中文件再进行打包签名(应用完整性校验)
- 股市总结
- 数字图像处理——灰度级、动态范围、对比度
- RMQ with Shifts
- ACM算法:悬线法
- Ubuntu 安装搜狗输入法
- Java基础总结(二)
- js jsp获取当前请求路径
- TCP/IP协议:传输层协议
- Linux Pthread 深入解析
- win32中int、float、short、double等占多少个字节
- Python增删改查MongoDB数据库
- Android 国际化string.xml 对应语言缩写