最大子矩阵(普通和01)

文章目录

    • 普通矩阵(单个矩阵值为任何数)
      • 最大子段和
      • 扩展到二维情况
    • 01矩阵(单个矩阵值为0或1)
    • 代码:

普通矩阵(单个矩阵值为任何数)

例题:POJ 1074
在这里插入图片描述
求出其中最大的子矩阵
答案是:
9 2
-4 1
-1 8
最大和是15
我们先想想如果不是矩阵,是一个数组,求其中连续的最长一段,咋做?

最大子段和

我们用b[i]来表示a[0]…a[1]的最大子段和
那么b [ i ] =max ( b [i - 1 ] + a [ i ], a [ i ] )
当a[n] 大于dp[n-1](前n-1个元素序列的最大子段和)。此时舍弃前面的子段和,即断开。
否则的话,把a[n]连接到前n-1个元素序列的最大和子段上,即dp[n] = dp[n-1] + a[n]

int MaxSum(int n,int *a)
{int sum=0,b=0;for(int i=0;i<n;i++){if(b>0) sum=max(sum,b+=a[i]);//不要忘了把b更新else sum=max(b=a[i],sum);}return sum;
}

扩展到二维情况

二维矩阵排列方式如图
参考题解
在这里插入图片描述
如果红色是我们要找的最大子矩阵
那和就是:(a[q][i]+…+a[p][i],a[q][i+1]+…+a[p][i+1],…,a[q][j]+…a[p][j])=(sum1,sum2,…,sumn
sum也就是每一列的相同行数相加
这不也是sun的一维数组,那其实就是一个一维数组的最大子段问题
如果把二维数组看成是纵向的一维数组和横向的一维数组

#include <iostream>
#include <cstring>
using namespace std;int maxsub(int a[], int n)
{int i, max = a[0], b = 0;for (i = 0; i < n; i++){if (b + a[i] >= a[i])	//当n-1的最大字段和+a[i]>=原来的最大字段和b += a[i];	//则n的最大字段和为b+a[i]else	//否则,就是a[i]b = a[i];if (b > max)	//找到最大的最大字段和max = b;}return max;
}int main()
{int n, i, j, k, maxsubrec, maxsubarr, m;int dp[101][101], arr[101];cin >> n >> m;for (i = 0; i < n; i++)for (j = 0; j < m; j++)cin >> dp[i][j];maxsubrec = dp[0][0];for (i = 0; i < n; i++)	//i用于标识从哪行开始,依次选择行{memset(arr, 0, sizeof(arr));for (j = i; j < n; j++)	//从第i行开始,j为选择几行{for (k = 0; k < m; k++)	//从1列选择到m列,压缩行arr[k] += dp[j][k];//arr表示每列的值maxsubarr = maxsub(arr, m);	//从每一个压缩行中选择最大字段和if (maxsubarr > maxsubrec) maxsubrec = maxsubarr;}}cout << maxsubrec << endl;return 0;
}

01矩阵(单个矩阵值为0或1)

参考题解
POJ - 3494
在这里插入图片描述
其实就是没有负数情况
我一开始想的是将最大子矩阵的代码中,如果一个数为0就赋值为-10000(这样程序就肯定不会选择这个块)
但是这样会超时
针对01矩阵我们可以这么想:
每一个单元格的值等于它所在列的连续1的数量,如果当前行为1,则当前行的值就等于上一行加1,如果当前行为0,则他的值也是0
我们扫描每一行,求出这一行中可形成的矩形最大面积,然后去最大情况即可
然后我们要用到一个单调递减的单调栈,
如果栈为空或者当前元素大于等于栈顶元素,则入栈
若栈非空且当前元素小于栈顶元素,则将栈顶弹出,更新面积最大值,直到栈空或者遇到第一个大于等于当前元素
将最后一个出栈的栈顶元素(最后一个大于当前元素的)向左右延伸,修改其值,并入栈。
核心都是对于每个高度为h的矩形,找到最左高度大于等于它的位置,和最右的位置。
在这里插入图片描述
我们看第三行:
0 1 3 2 0 0 0
0先入栈,然后1入栈,然后3入栈,然后到2时,2<3,计算此时的矩阵面积=(4-3) * 3=3,此时最大面积是3,然后将值3改为2,此时就是0 1 2 2 ,然后0<2,计算此时面积 = (5-3) * 2=4,最大面积就是4,一次类推,都是按照这个操作

代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stack>
using namespace std;int main()
{//top指向栈顶;tmp为临时变量,记录面积的值;ans为答案,记录面积的最大值 int i,j,m,n,x,top,tmp,ans,h[2020],a[2020];stack<int> st; //单调栈,记录位置 while(~scanf("%d%d",&m,&n)){ans=0;memset(h,0,sizeof(h)); //用于第一行的处理for(i=0;i<m;i++){ //扫描每一行 for(j=1;j<=n;j++){scanf("%d",&x);if(x==1) h[j]=h[j]+1; //如果是1,则在上一行本列的基础上+1 else h[j]=0; //否则为0 a[j]=h[j]; //a数组用来向左右扩展}a[n+1]=-1; //设最后元素为最小值,以最后让栈内元素出栈 for(j=1;j<=n+1;j++){if(st.empty()||a[j]>=a[st.top()]){ //如果栈为空或入栈元素大于等于栈顶元素,则入栈 st.push(j);}else{while(!st.empty()&&a[j]<a[st.top()]){ //如果栈非空并且入栈元素小于栈顶元素,则将栈顶元素出栈 top=st.top();st.pop();tmp=(j-top)*a[top]; //计算面积值 if(tmp>ans) ans=tmp; //更新面积最大值 }st.push(top); //将最后一次出栈的栈顶元素延伸并入栈 a[top]=a[j]; //修改其对应的值 }}}printf("%d\n",ans);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319907.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动化流程开源框架BotSharp

BotSharp是一款为方便构建智能对话机器人平台而开发的开源框架&#xff0c;最大的特点是所有模型算法都是基于.NET Core开发实现&#xff0c;甚至最基本的Penn Treebank分词标准&#xff0c;都重新用C#实现了。在机器学习python占绝对优势的时代算是不可多得的项目。该项目涉及…

二分图匹配

定义&#xff1a; 二分图&#xff1a;一个图被分成了两部分&#xff0c;相同的部分没有边 匹配&#xff1a;二分图G的子图M中&#xff0c;M的边集{E}中的任意两条边都不指向同一个顶点 极大匹配&#xff1a;在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹…

【整体二分】区间第k小(金牌导航 整体二分-1)

区间第k小 金牌导航 整体二分-1 题目大意 给出一个序列&#xff0c;有若干查询&#xff0c;每次查询给出l,r,k&#xff0c;让你求l~r这个区间的第k大 输入样例 7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3输出样例 5 6 3数据范围 1⩽n⩽105,1⩽m⩽50000,1⩽∣ai∣⩽1091\leqsla…

积极参与开源项目,促进.NET Core生态社区发展

今天早上在微信群里聊天聊到百度的SDK 已经支持.NET Core, 百度已经在3月份就支持了&#xff0c;想起当时还是我在他们的github上提的issue&#xff1a; https://github.com/Baidu-AIP/dotnet-sdk/issues/3。.NET Core生态社区的发展已经四年多时间&#xff0c;日趋完善&#x…

P6091-[模板]原根

正题 题目链接:https://www.luogu.com.cn/problem/P6091 题目大意 给出一个数ppp&#xff0c;求出它的所有在[0,p][0,p][0,p]的原根。 解题思路 原根的定义&#xff0c;δp(a)\delta_p(a)δp​(a)表示一个最小的nnn使得an≡1(modp)a^n\equiv1(mod\ p)an≡1(mod p)&#xff0…

并查集小记

有什么用&#xff1a; 查询元素a和元素b是否属于同一组 合并元素a和元素b所在组 代码实现&#xff1a; #include<iostream> using namespace std; int n,m,p; int fa[5001]; int find(int x){if(fa[x]x) return x;else{return fa[x]find(fa[x]);} } int main(){cin&g…

Poj 1011 UVA - 307 Sticks

牛客网 poj 1011 题目&#xff1a; George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long th…

HAPPY2020暑假训练前复习

A.计蒜客 - T1381 输出hello world 万恶之源 B.51Nod - 2060 全排列输出 不要用STL的next_permutation,会超时 #include <bits/stdc.h> using namespace std; const int maxn14; int dt[maxn]; int vis[maxn];int n; void dfs(int depth) {if(depthn){for(int i0;; i…

【LCT】洞穴勘测(luogu 2147/金牌导航 LCT-1)

洞穴勘测 luogu 2147 金牌导航 LCT-1 题目大意 给你若干操作&#xff0c;有三种操作&#xff1a; 1.连接两个点 2.吧两个点之间的连边断掉&#xff08;保证有这条边&#xff09; 3.查询两个点之间是否连通 样例 #1 输入样例 #1 200 5 Query 123 127 Connect 123 127 Que…

Service Fabric 与Ocelot 的集成

概要云应用程序通常都需要使用前端网关&#xff0c;为用户、设备或其他应用程序提供同一个入口点。 在 Service Fabric 中&#xff0c;网关可以是任意无状态服务&#xff08;如 ASP.NET Core 应用程序&#xff09; 。本文介绍了如何将Ocelot用作 Service Fabric 应用程序的网关…

图论复习——最短路

知识点 最短路径算法 最短路径树 每个点uuu的父亲为使uuu得到最短距离的前驱节点&#xff0c;若有多个&#xff0c;则取任意一个。 题目 CF449B Jzzhu and Cities Blog CF464E The Classic Problem Blog [XSY3888] 传送门 对每个点uuu&#xff0c;记d(u)d(u)d(u)表示uuu…

Loj#143-[模板]质数判定【Miller-Rabin】

正题 题目链接:https://loj.ac/p/143 题目大意 给出一个数ppp&#xff0c;让你判定是否为质数。 解题思路 Miller−RabinMiller-RabinMiller−Rabin是一种基于费马小定理和二次探测定理的具有较高正确性的高效质数判定算法。 首先讲一下两个定理 费马小定理&#xff1a;gcd(…

【LCT】Tree II(luogu 1501)

Tree II luogu 1501 题目大意 给出一棵树&#xff0c;让你进行若干操作&#xff0c;操作如下&#xff1a; 1.把两个点路径上的所有点权值加k 2.把两个点路径上的所有点权值乘k 3.把一条边断开&#xff0c;连上另一条边 4.查询两个点路径上的权值和 输入样例 3 2 1 2 2 3 *…

图论复习汇总

三元环计数&四元环计数 Blog dfs树,点双,边双,强连通分量 Blog bfs树 对一个图运行 bfs 算法&#xff0c;每个点uuu的父亲定义为第一次遍历uuu时的前驱结点&#xff0c;若无则为根。 非树边只存在在同一层的两个点和相邻层的点中。 hihoCoder1147 时空阵 题意&#x…

P4718-[模板]Pollard-Rho算法

正题 题目链接:https://www.luogu.com.cn/problem/P4718 题目大意 给出一个数nnn&#xff0c;如果它是质数则输出PrimePrimePrime&#xff0c;否则输出它的最大质因子。 解题思路 Pollard-Rho\text{Pollard-Rho}Pollard-Rho算法的前置知识是Miller-Rabin\text{Miller-Rabin}M…

T-Dongle-S3开发笔记——创建工程

创建Hello world工程 打开命令面板 方法1&#xff1a;查看->命令面板 方法2&#xff1a;按F1 选择ESP-IDF:展示示例项目 创建helloworld 选择串口 选择芯片 至此可以编译下载运行了 运行后打印的信息显示flash只有2M。但是板子上电flash是W25Q32 4MB的吗 16M-bit

hdu 1576 A/B

文章目录题目&#xff1a;题解&#xff1a;代码&#xff1a;hdu 1576题目&#xff1a; 要求(A/B)%9973&#xff0c;但由于A很大&#xff0c;我们只给出n(nA%9973)(我们给定的A必能被B整除&#xff0c;且gcd(B,9973) 1)。 Input 数据的第一行是一个T&#xff0c;表示有T组数据。…

ASP.NET Core 中断请求了解一下(翻译)

本文所讲方式仅适用于托管在Kestrel Server中的应用。如果托管在IIS和IIS Express上时&#xff0c;ASP.NET Core Module(ANCM)并不会告诉ASP.NET Core在客户端断开连接时中止请求。但可喜的是&#xff0c;ANCM预计在.NET Core 2.2中会完善这一机制。1. 引言假设有一个耗时的Act…

子数整数(luogu 1151)

子数整数 luogu 1151 题目大意 给出一个数k&#xff0c;让你在10000~30000中求出满足前三位&#xff0c;中间三位&#xff0c;后三位都可被k整除的数 输入样例 15输出样例 22555 25555 28555 30000数据范围 0<k<1000 解题思路 暴力枚举 代码 #include<cstd…

2021-10-22

扫描线&#xff1a; https://www.cnblogs.com/Parsnip/p/10887135.html https://blog.csdn.net/Emma2oo6/article/details/120584307 https://blog.csdn.net/weixin_30609331/article/details/96234492 LIS& LCS https://www.xuebuyuan.com/586419.html https://blog.csdn…