求最大子矩阵的两种思路

求最大子矩阵的两种思路
求最大子矩阵的两种思路

求最大子矩阵的两种思路

长沙市雅礼中学贺一骏

编者:求最大子矩阵问题是很常见的一类问题,具有很强的代表性,通过这个问题,可以派生出更加复杂的问题,也可以学到很多常用的问题处理手段。

问题描述

一个被分为n*m个格子的月饼盒,第i 行第j 列位置的格子里面有a [ i , j ]个月饼。本来CCC老师打算送这盒月饼给某人的,但是就在要送出月饼盒的前一天晚上,一只极其可恶的老鼠夜袭月饼盒,有部分格子被洗劫并且穿了洞。CCC老师必须尽快从这个月饼盒里面切割出一个矩形月饼盒,新的月饼盒不能有洞,并且CCC老师希望保留在新月饼盒内的月饼的总数尽量多。

任务:请帮CCC老师设计一个程序,计算一下新月饼盒最多能够保留多少月饼。

输入

文件的第一行有两个整数n、m。第i + 1 行的第j 个数表示 a [ i , j ],如果这个数为0 ,则表示这个位置的格子被洗劫过。其中:1 ≤n,m ≤300,0 ≤a [ i , j ]≤255

输出

在文件中写入最大月饼数。

样例

Sample Input

3 4

1 2 3 4

5 0

6 3

10 3 4 0

Sample Output

17

分析

该问题实际上是求在给定平面区域中找出一个最大的子矩形,要求该矩形不能包含某些限定的格子。

方法一:

我们初次见到这个问题,可能最直接的想法就是枚举。即枚举每个矩阵的左上角坐标(x1,y1)和右下角坐标(x2,y2),然后统计这个矩阵是否满足题设条件。我们可以先预处理从左上角(1,1)出发到任意一点(i,j)的月饼数目area(i,j),预处理的时间复杂度为O(mn),程序如下:

For i:=1 to n do

For j:=1 to m do

Area[I,j]:=area[i-1,j]+area[i,j-1]-area[i-1,j-1]+mooncake[i,j];

其边界条件为area[0,i]=0,area[i,0]=0

Mooncake[i,j]表示(i,j)这个点的上月饼数目,如果(i,j)这个点被破坏,则设mooncake[i,j]=-30000000,那么有area[i,j]<0。

显然,对于给定的两个点A(x1,y1)、B(x2,y2),我们可以算术方法计算该矩形的和,如下图所示:

图1 预处理计算过程图

主程序如下:

For x1:=1 to n do

For x2:=x1 to n do

For y1:=1 to m do

For y2:=y1 to m do

Begin

Sum:=area[x2,y2]-area[x1-1,y2]-area[x2,y1-1]+area[x1-1,y1-1];

If sum>0 then updateans(sum);

End;

因此算法的时间复杂度为O(m2n2)。

从上述程序中可以看出,枚举点的坐标和预处理的过程有多次重复操作,也就是说在上述算法的运算中存在着很多冗余运算,如果我们能消除这些冗余运算,将能提高程序效率。下面请看算法二。

方法2

如何减少冗余呢?我们不妨这样的思考,上面的枚举实际将所有的矩形,不管有用无用全部枚举了出来。其实,对于大部分无用的矩形是可以不需要枚举就可以排除在最优解之外的,而有用的矩形指的是那些极大化矩形。

所谓极大化的矩形就是指那些不能再通过扩展边来再次增大面积的矩形。这样的矩形之所以无法再扩展是因为它们的四条边要么靠障碍物,要么靠着边界。例如下图中A的黄色部分就是一个极大化矩形,而B不是(它的右边界还可以向右延伸到边界),因此我们可以根据这一特点来找到所有的极大化矩形。

图2 极大化矩形

为了完成寻找极大化矩形的工作,我们先来看一个这样的子问题:

问题描述:给出若干个连在一起的高塔,已知每个塔的高度,询问对于每个高塔而言向左、右延伸的距离分别是多少(所谓延伸就是指向一个方向不断的寻找,直到找到一个高度低于本身的高塔或者边界为止,如下图)。

图3 塔的示意图及相关变量定义

说明:上图中p[i]为塔的坐标,h[i]为塔的高度,l[i]为塔尖向左延伸的最远坐标位置,r[i]为塔尖向右延伸的最远坐标位置

这里,我们只考虑向右的情况。向左操作类似。

我们从右向左扫描,当求r[i]时,r[i+1..n]已求出。首先,令r[i]=i,当h[i]<=h[r[i]+1]时,就表示位置i向右最多可以延伸到位置r[r[i]+1],更新r[i],然后,继续比较h[i]与h[r[i]+1]的大小,不断的更新r[i],直到h[i]>h[r[i]+1]为止。

图4、5、6演示了k=4时的操作过程。

图4 步骤1,赋初值r[4]=4

图5 步骤2,向右更新r[4]=6

图6 步骤3,向右更新r[4]=9

代码如下(向右延伸):

For i:=m downto 1 do

Begin

R[i]:=I;

While (r[i]<>m)and(h[i]<=h[r[i]+1]) do r[i]:=r[r[i]+1];

End;

这样做完后r[i]里保存的就是每个位置向右扩展的最远距离了。因为每个位置最多被后面的位置合并一次,因此这个算法的时间复杂度为O(N)。

回到原问题,下面来看看如何求极大化矩形。

枚举原矩形的每一行,首先更新h[i],这里的h[i]表示第i列从当前行往上数有多少格连续没有被损坏的格子(直到上边界为止)。显然,这里的h[i]和子问题中的h[i]相同。因此利用处理子问题的方法,求出l[i]和r[i],接着根据l[i]和r[i],对于当前行的每一个位置k,有长为r[k]-l[k]+1,宽为h[k]的符合题设要求的矩形,并且这个矩形就是极大化矩形,算法一中的预处理方法,可求出这个矩形中月饼数目。

下面来分析一下时间复杂度:

枚举每一行,时间复杂度为O(N),更新h[i] 为O(M),求l[i]和r[i]为O(M),枚举k,为O(M),因此,总时间复杂度为O(NM),是一个非常优秀的算法。

思考与总结:

对于这类问题往往一开始就会有一些简单的想法,虽然实际效果并不是非常好,但是其思考方法总是可以借鉴的。像本题中就由简单的枚举出发,利用枚举矩形这个思考方式不断的优化,从而得到一个优秀的算法。

像这类问题的还有:

Zoj2069 white rectangles

Zoj1985 largest rectangle in a histogram等

三元组表示稀疏矩阵的转置(一般算法和快速算法)

一、设计要求 1.1 问题描述 稀疏矩阵是指那些多数元素为零的矩阵。利用稀疏特点进行存储和计算可以大大节省存储空间,提高计算效率。求一个稀疏矩阵A的转置矩阵B。 1.2需求分析 (1)以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现稀疏矩阵的转置运算。(2)稀疏矩阵的输入形式采用三元组表示,运算结果则以通常的阵列形式列出。 (3)首先提示用户输入矩阵的行数、列数、非零元个数,再采用三元组表示方法输入矩阵,然后进行转置运算,该系统可以采用两种方法,一种为一般算法,另一种为快速转置算法。(4)程序需要给出菜单项,用户按照菜单提示进行相应的操作。 二、概要设计 2.1存储结构设计 采用“带行逻辑链接信息”的三元组顺序表表示矩阵的存储结构。三元组定义为:typedef struct { int i;//非零元的行下标 int j;//非零元的列下标 ElemType e; //非零元素值 }Triple; 矩阵定义为: Typedef struct { Triple data[MAXSIZE+1]; //非零元三元组表 int rpos[MAXRC+1]; //各行第一个非零元的位置表 int mu,nu,tu; //矩阵的行数、列数和非零元个数 }RLSMatrix; 例如有矩阵A,它与其三元组表的对应关系如图

2.2 系统功能设计 本系统通过菜单提示用户首先选择稀疏矩阵转置方法,然后提示用户采用三元组表示法输入数据创建一个稀疏矩阵,再进行矩阵的转置操作,并以通常的阵列形式输出结果。主要实现以下功能。 (1)创建稀疏矩阵。采用带行逻辑连接信息的三元组表表示法,提示用户输入矩阵的行数、列数、非零元个数以及各非零元所在的行、列、值。 (2)矩阵转置。<1>采用一般算法进行矩阵的转置操作,再以阵列形式输出转置矩阵B。 <2>采用快速转置的方法完成此操作,并以阵列形式输出转置矩阵B。 三、模块设计 3.1 模块设计 程序包括两个模块:主程序模块、矩阵运算模块。 3.2 系统子程序及其功能设计 系统共设置了8个子程序,各子程序的函数名及功能说明如下。 (1)CreateSMatrix(RLSMatrix &M) //创建稀疏矩阵 (2)void DestroySMatrix(RLSMatrix &M) //销毁稀疏矩阵 (3)void PrinRLSMatrix(RLSMatrix M) //遍历稀疏矩阵 (4)void print(RLSMatrix A) //打印矩阵函数,输出以阵列形式表示的矩阵 (5)TransposeSMatrix(RLSMatrix M,RLSMatrix &T) //求稀疏矩阵的转置的一般算法(6)FastTransposeSMatrix(RLSMatrix M,RLSMatrix &T) //快速转置算法 (7)void showtip() //工作区函数,显示程序菜单 (8)void main() //主函数

最大子矩阵问题

学习材料:王知昆《浅谈用极大化思想解决最大子矩阵问题》 【最大子矩阵问题】 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的、轮廓与整个矩形平行或重合的最大子矩形。 【定义子矩形】 有效子矩形:内部不包含障碍点的、轮廓与整个矩形平行或重合的子矩形。 极大子矩形:每条边都不能向外扩展的有效子矩形。 最大子矩形:所有有效子矩形中最大的一个(或多个)。 【极大化思想】 在一个有障碍点的矩形中最大子矩形一定是极大子矩形。 设计算法的思路:枚举所有的极大子矩形,找到最大子矩形。 设NM分别为整个矩形的长和宽,S为内部的障碍点数。 【算法1】 时间复杂度:O(S^2)空间复杂度:O(S) 由于极大子矩形的每一条边都不能向外扩展,那么极大子矩阵的每条边要么覆盖了障碍点,要么与整个矩形的边界重合 基本算法:枚举上下左右四个边界,然后判断组成的矩形是否是有效子矩形。 复杂度:O(S^5)可以改进的地方:产生了大量的无效子矩形。 初步改进的算法:枚举左右边界,然后对处在边界内的点排序,每两个相邻的点和左右边界组成一个矩形。 复杂度:O(S^3)可以改进的地方:枚举了部分不是极大子矩形的情况。 综上,设计算法的方向: 1、保证每一个枚举的矩形都是有效的。 2、保证每一个枚举的矩形都是极大的。 算法的过程: 枚举极大子矩形的左边界——>根据确定的左边界,找出相关的极大子矩形——>检查和处理遗漏的情况 (1)按照横坐标从小到大的顺序将所有的点编号为1,2,3... (2)首先选取1号点作为要枚举的极大子矩形的左边界,设定上下边界为矩形的上下边界

(3)从左到右扫描,第一次到2号点,确定一个极大子矩形,修改上下边界;第二次找到3号点,以此类推。 (4)将左边界移动到2号点,3号点,,,以同样的方法枚举 遗漏的情况: 1、矩形的左边界与整个矩形的左边界重合。解决方法:用类似的方法从左到右扫一遍 2、矩形的左边界与整个矩形的左边界重合,且矩形的右边界与整个矩形的右边界重合。解决方法:预处理时增加特殊判断。 优点:利用的极大化思想,复杂度可以接受,编程实现简单。 缺点:使用有一定的局限性,不适合障碍点较密集的情况。 【算法2】 时间复杂度O(NM) 空间复杂度O(NM) 定义 有效竖线:除了两个端点外,不覆盖任何一个障碍点的竖直线段。 悬线:上端覆盖了一个障碍点或者到达整个矩形上边界的有效线段。 每个悬线都与它底部的点一一对应,矩形中的每一个点(矩形顶部的点除外)都对应了一个悬线。 悬线的个数=(N-1)*M; 如果把一个极大子矩形按照横坐标的不同切割成多个与y轴平行的线段,那么其中至少有一个悬线。 如果把一个悬线向左右两个方向尽可能的移动,那么就得到了一个矩形,我们称它为悬线对应的矩形。 悬线对应的矩形不一定是极大子矩形,因为下边界可能还可以向下扩展。 设计算法: 原理:所有悬线对应矩形的集合一定包含了极大子矩形的集合。 通过枚举所有的悬线,找出所有的极大子矩形。 算法规模: 悬线个数=(N-1)×M 极大子矩形个数≤悬线个数 具体方法: 设H[i,j]为点(i,j)对应的悬线的长度。

稀疏矩阵的建立与转置

实验2 稀疏矩阵的建立与转置 一、实验目的 掌握特殊矩阵的存储和操作算法。 二、实验内容及问题描述 实现用三元组保存稀疏矩阵并实现矩阵转置的算法。 三、实验步骤 1. 定义稀疏矩阵的三元组形式的存储结构。 2. 实现三元组矩阵的传统转置算法。 3. 实现三元组矩阵的快速转置算法。 4. 输入矩阵非零元素,测试自己完成的算法。 四、程序流程图

五、概要设计 矩阵是很多的科学与工程计算中研究的数学对象。在此,我们感兴趣的是,从数学结构这门学科着眼,如何存储矩阵的元从而使矩阵的各种运算有效的进行。本来,用二维数组存储矩阵,在逻辑上意义是很明确的,也很容易理解,操作也很容易和方便。但是在数值分析中经常出现一些阶数很高的矩阵,同时,在矩阵中又有很多值相同或者都为零的元素,可以对这种矩阵进行压缩存储:对多个值相同的元素只分配一个存储空间;对零元素不分配空间。稀疏矩阵的定义是一个模糊的定义:即非零元个数较零元个数较少的矩阵。例如下图所示的矩阵 为一个稀疏矩阵。为了实现稀疏矩阵的这种存储结构,引入三元组这种数据结构。三元组的线性表顺存储形式如下图: 六、详细设计 sanyuanzu.h 头文件 #define max 100 typedef struct { int row,col; int e; }Triple;//定义三元组 typedef struct { Triple data[max]; int mu,nu,tu; }TSMatrix;///*定义三元组的稀疏矩阵*/ void creat( TSMatrix &M) ; void fasttrans(TSMatrix A,TSMatrix &B);

数据结构与算法 特殊矩阵和稀疏矩阵

常熟理工学院 《数据结构与算法》实验指导与报告书 _2017-2018_____学年第__1__ 学期 专业:物联网工程 实验名称:特殊矩阵和稀疏矩阵 实验地点: N6-210 指导教师:聂盼红 计算机科学与工程学院 2017

实验五特殊矩阵和稀疏矩阵 【实验目的】 1、掌握数组的结构类型(静态的内存空间配置);通过数组的引用下标转换成该数据在内存中的地址; 2、掌握对称矩阵的压缩存储表示; 3、掌握稀疏矩阵的压缩存储-三元组表表示,以及稀疏矩阵的转置算法。 【实验学时】 2学时 【实验预习】 回答以下问题: 1、什么是对称矩阵?写出对称矩阵压缩存储sa[k]与aij之间的对应关系。 若n阶矩阵A中的元素满足下述性质:a ij=a ji,则称为n阶对称矩阵。 sa[k]与矩阵元素a ij之间存在着一一对应的关系: 若i>=j,k=i*(i+1)/2+j; 若i

的关系。(注意C程序中,i,j,k均从0开始) (2)调试程序与运行。对称矩阵存储下三角部分即i>=j。 对称矩阵为3,9,1,4,7 9,5,2,5,8 1,2,5,2,4 4,5,2,1,7 7,8,4,7,9 参考程序如下: #include<> #define N 5 int main() { int upper[N][N]= {{3,9,1,4,7}, {9,5,2,5,8}, {1,2,5,2,4}, {4,5,2,1,7}, {7,8,4,7,9} }; /*对称矩阵*/ int rowMajor[15]; /*存储转换数据后以行为主的数组*/ int Index; /*数组的索引值*/ int i,j; printf("Two dimensional upper triangular array:\n"); for (i=0; i

现代控制理论矩阵的复习

矩阵的复习(现代控制理论用) (线性代数的复习) 一. 矩阵 矩阵定义为矩形阵列表,它的元素可能是实数、复数、函数或算子,表中每一个元素表示一定的数学概念或工程信息,则此矩形表整体称为矩阵。 ?? ??? ?? ??=nn n n n n a a a a a a a a a A 2 1 22221 11211 ??? ? ?? ? ??=jk j k k b b b b b b B 1221111 其中A 具有n 行与m 列,ij a 表示矩阵A 的第i 行,第j 列元素。 矩阵B 为第j 行,k 列,即=A (ij a ),=B (jk b ) 当n=m 时称为方阵,可表示为 ?? ?? ? ? ? ??=?nn n n n n a a a a a a a a a 2 1 2222111211 =det(A) 称为方阵A 的n 阶行列式。 1. 子式或子行列式 给定n 阶行列式及其任一元素jk a ,划去△的j 行第k 列的全部元素而得到一个(n-1)阶行列式,称为原行列式的一个子行列式,简称子式,以jk ?表示。 即:33 32 31 2322 21 131211 a a a a a a a a a =? 划掉23a 的子行列式 32 3112 1123a a a a = ? 23?=?jk j=2 k=3 23a a jk = n 阶行列式则有n 行n 列共2n 个子式。 2. 余因子或代数余子式 如果用() k j +-1去乘jk a 的子式jk ?得到的结果称为jk a 的余因子或代数余子式。 () 3 2231+-=A - =?2332 3112 11a a a a 一般为() jk k j jk A ?-=+1 ,其余类推。

基于三元组表表示的稀疏矩阵的快速转置算法及其改进

基于三元组表表示的稀疏矩阵的快速转置算法及其改进 摘要:介绍基于三元组表表示的稀疏矩阵的快速转置算法,此算法在转置前需要先确定原矩阵中各列第一个非零元在转置矩阵中的位置,在此使用2个数组作为辅助空间,为了减少算法所需的辅助空间,通过引入2个简单变量提出一种改进算法。该改进算法在时间复杂度保持不变的情况下,空间复杂度比原算法节省一半。 需求分析:矩阵作为许多科学与工程计算的数据对象,必然是计算机处理的数据对象之 一。在实际应用中,常会遇到一些阶数很高,同时又有许多值相同的元素或零元素的矩阵,在这类矩阵中,如果值相同的元素或零元素在矩阵中的分配没有规律,则称之为稀疏矩阵。为了节省存储空间,常对稀疏矩阵进行压缩存储。压缩存储的基本思想就是:对多个值相同的元素只分配1个存储空间,对零元素不分配存储空间。换句话说,就是只存储稀疏矩阵中的非零元素。稀疏矩阵可以采取不同的压缩存储方法,对于不同的压缩存储方法,矩阵运算的实现也就不同。 1.稀疏矩阵的三元组表表示法 根据压缩存储的基本思想,这里只存储稀疏矩阵中的非零元素,因此,除了存储非零元的值以外,还必须同时记下它所在行和列的位置(i,j),即矩阵中的1个非零元aij由1个三元组(i,j,aij)惟一确定。由此可知,稀疏矩阵可由表示非零元的三元组表及其行列数惟一确定。对于稀疏矩阵的三元组表采取不同的组织方法即可得到稀疏矩阵的不同压缩存储方法,用三元组数组(三元组顺序表)来表示稀疏矩阵即为稀疏矩阵的三元组表表示法。三元组数组中的元素按照三元组对应的矩阵元素在原矩阵中的位置,以行优先的顺序依次存放。 三元组表的类型说明如下: # define MAXSIZE 1000 /*非零元素的个数最多为 1000*/ typedef struct { int row,col; /*该非零元素的行下标和列下标*/ ElementType e; /*该非零元素的值*/ }Triple; typedef struct { Triple data[MAXSIZE+1]; /*非零元素的三元组表, data[0]未用*/ int m,n,len; /*矩阵的行数、列数和非零元素的个数*/ }TSMatrix; 2.稀疏矩阵的快速转置算法 待转置矩阵source和转置后矩阵dest分别用三元组表A和B表示,依次按三元组表A中三元组的次序进行转置,转置后直接放到三元组表B的正确位置上。这种转置算法称为快速转置算法。为了能将待转置三元组表A中元素一次定位到三元组表B的正确位置上,需要预先计算以下数据: 1)待转置矩阵source每一列中非零元素的个数(即转置后矩阵dest每一行中非零元素的个 数)。

稀疏矩阵(算法与数据结构课程设计)

稀疏矩阵 一、问题描述 假若在n m ?阶中,有t 个元素不为零,令n m t ?=δ称为矩阵的稀疏因子。通常认为≤δ0.05时称为稀疏矩阵。稀疏矩阵的研究大大的减少了数据在计算机中存储所需的空间,然而,它们的运算却与普通矩阵有所差异。通过本次实验实现稀疏矩阵的转置、加法和乘法等多种运算。 二、基本要求 1、稀疏矩阵采用三元组表示,建立稀疏矩阵,并能按矩阵和三元组方式输出; 2、编写算法,完成稀疏矩阵的转置操作; 3、编写算法,完成对两个具有相同行列数的稀疏矩阵进行求和操作; 4、编写算法,对前一矩阵行数与后一矩阵列数相等的两个矩阵,完成两个稀疏矩阵的相乘操作。 三、测试数据 1、转置操作的测试数据: ??????? ? ?00200013000010020100 2、相加操作的测试数据: ??????? ? ?002000130000100 20100 ??????? ??00200010000210030300 3、相乘操作的测试数据: ?????? ? ??000000030040 0021 ??????? ??001002000021 四、算法思想 1、三元组结构类型为Triple ,用i 表示元素的行,j 表示元素的列,e 表示元素值。稀疏矩阵的结构类型为TSMatrix ,用数组data[]表示三元组,mu 表示行数,nu 表示列数,tu 表示非零元个数。 2、稀疏矩阵转置的算法思想 将需要转置的矩阵a 所有元素存储在三元组表a.data 中,按照矩阵a 的列序来转置。

为了找到a的每一列中所有非零元素,需要对其三元组表a.data扫描一遍,由于a.data 是以a的行需序为主序来存放每个非零元的,由此得到的就是a的转置矩阵的三元组表,将其储存在b.data中。 3、稀疏矩阵相加的算法思想 比较满足条件(行数及列数都相同的两个矩阵)的两个稀疏矩阵中不为0的元素的行数及列数(即i与j),将i与j都相等的前后两个元素值e相加,保持i,j不变储存在新的三元组中,不等的则分别储存在此新三元组中。最后得到的这个新三元组表就是两个矩阵的和矩阵的三元组表。 4、稀疏矩阵相乘的算法思想 两个相乘的矩阵为M与N,对M中每个元素M.data[p](p=1,2,…,M.tu),找到N中所有满足条件M.data[p].j=N.data[q].i的元素N.data[q],求得M.data[p].v和N.data[q].v 的乘积,又T(i,j)=∑M(i,k)×N(k,j),乘积矩阵T中每个元素的值是个累计和,这个乘积M.data[p].v×N.data[q].v只是T[i][j]中的一部分。为便于操作,应对每个元素设一累计和的变量,其初值是零,然后扫描数组M,求得相应元素的乘积并累加到适当的求累计和的变量上。由于T中元素的行号和M中元素的行号一致,又M中元素排列是以M的行序为主序的,由此可对T进行逐行处理,先求得累计求和的中间结果(T的一行),然后再压缩存储到Q.data中去。 五、模块划分 1、Status CreateM(TSMatrix *M, int a[],int row, int col),创立三元组; 2、void PrintM(TSMatrix M),按数组方式输出; 3、void PrintM3(TSMatrix M),按三元组方式输出; 4、Status TransposeSMatrix(TSMatrix M, TSMatrix *T),稀疏矩阵的转置; 5、Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix *Q),稀疏矩阵加法; 6、Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix *Q),稀疏矩阵相乘; 7、main(),主函数。 六、数据结构//(ADT) 1、三元组结构类型 typedef struct { int i,j; ElemType e; } Triple; 2、稀疏矩阵 typedef struct { Triple data[MAXSIZE+1];

最大子矩阵问题总结

Largest Rectangle in a Histogram Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 53 Accepted Submission(s) : 8 Problem Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles: Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram. Input The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1 <= n <= 100000. Then follow n integers h1, ..., hn, where 0 <= hi <= 1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case. Output For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line. Sample Input 7 2 1 4 5 1 3 3 4 1000 1000 1000 1000

稀疏矩阵的运算(完美版)

专业课程设计I报告(2011 / 2012 学年第二学期) 题目稀疏矩阵的转换 专业软件工程 学生姓名张鹏宇 班级学号 09003018 指导教师张卫丰 指导单位计算机学院软件工程系 日期 2012年6月18号

指导教师成绩评定表

附件: 稀疏矩阵的转换 一、课题内容和要求 1.问题描述 设计程序用十字链表实现稀疏矩阵的加、减、乘、转置。 2.需求分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 二、设计思路分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 三、概要设计 为了实现以上功能,可以从3个方面着手设计。 1.主界面设计 为了实现对稀疏矩阵的多种算法功能的管理,首先设计一个含有多个菜单项的主

控菜单子程序以链接系统的各项子功能,方便用户交互式使用本系统。本系统主控菜单运行界面如图所示。 2.存储结构设计 本系统采用单链表结构存储稀疏矩阵的具体信息。其中:全部结点的信息用头结点为指针数组的单链表存储。 3.系统功能设计 本系统除了要完成稀疏矩阵的初始化功能外还设置了4个子功能菜单。稀疏矩阵的初始化由函数i typedef int ElemType 实现。建立稀疏矩阵用void Creat()实现,依据读入的行数和列数以及非零元素的个数,分别设定每个非零元素的信息。4个子功能的设计描述如下。 (1)稀疏矩阵的加法: 此功能由函数void Xiangjia( )实现,当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。然后进行加法,最后输出结果。 (2)稀疏矩阵的乘法: 此功能由函数void Xiangcheng( )实现。当用户选择该功能,系统提示输

矩阵文档

成都信息工程学院 课程设计 题目:魔方矩阵 作者姓名: 班级: 学号: 指导教师: 日期:年月日 作者签名

摘要 我的实践题目是对C语言程序设计——魔方矩阵,主要的要求:采用菜单形式,至少包含输入矩阵、保存矩阵、载入矩阵、退出;输入整数N,输出N*N 的二阶矩阵;每一行,每一列以及两条对角线之和相等;程序中应能判断N的合法性及合理性; N最大值不得小于20;并指定行的排序,排序方法不限,排序后且能按排序后的结果保存到文件中,并且能够下一次载入;每次输出一个矩阵,同时在下面输出素数、水仙花数。此次的系统我还添加了一个注册模块。 本实践能够充分的考核我们对C语言的熟悉度以及实践能力,对我们更多学习与了解C语言有极大的帮助,因此这次实践是十分有必要的。 我的设计内容就是利用if条件语句、for循环语句以及条件判断语句等函数及指针的合理使用,通过不断的运行,调试,输出,对本程序进行合理的解决,对魔方矩阵,文件,素数,水仙花数的算法进一步的了解掌握。 关键字:C语言for循环if条件魔方矩阵素数水仙花数

目录 1引言 (3) 1.1课题背景 (3) 1.2本课题的主要工作 (4) 2魔方矩阵系统需求分析及开发工具 (4) 2.1系统应具备的基本功能 (4) 2.2开发环境及工具 (5) 2.2.1 运行环境 (5) 2.2.2 c语言简介 (5) 2.2.3 for循环语句介绍 (5) 2.2.4 if条件语句介绍 (6) 3系统总体结构设计 (6) 3.1 基本简介 (6) 3.2 算法设计 (6) 3.3 系统功能模块设计简介 (9) 3.3.1 魔方矩阵模块 (9) 3.3.2文件的读与写 (15) 4系统测试与分析 (17) 4.1 测试 (17) 4.2 测试过程中遇到的问题 (17) 5 结论 (18) 6参考文献 (18)

稀疏矩阵快速转置

题目:假设稀疏矩阵A采用三元组表表示,编写程序实现该矩阵的快速转置 要求:输入一个稀疏矩阵A,由程序将其转换成三元组表存储;转置后的三元组表,由程序将其转换成矩阵形式后输出。 一、需求分析 1.用户可以根据自己的需求输入任意一个稀疏矩阵,通过程序将其转换成三元组存储方式; 2.并且能够完成矩阵的转置功能,要求需要使用的方法是快速转置的方法。 3.最后要够显示原矩阵和转置后的矩阵让用户能进行比较。 4.程序执行的命令包括: (1)构造稀疏矩阵M (2)求转转矩阵T (3)显示(打印)矩阵 二、概要设计 ⒈为实现上述算法,需要线性表的抽象数据类型: ADT SparseMatrix { 数据对象:D={a ij :|a ij ∈TermSet,i=1…m,m≥0,j=1…n,n≥0 m和n分别成为矩阵的行数和列数 } 数据关系:R={Row,Col} Row ={|1≤i≤m,1≤j≤n-1 } Col ={|1≤i≤m-1,1≤j≤n } 基本操作: CreateSMtrix(& M) 操作结果:创建稀疏矩阵M。 DestroySMaix(&M) 初始条件:稀疏矩阵M已存在。 操作结果:销毁稀疏矩阵M。 PrintSMatrix(L) 初始条件:稀疏矩阵M已经存在。 操作结果:输出稀疏矩阵M。 CopySMatrix(M,&T) 初始条件:稀疏矩阵M已经存在。 操作结果:由稀疏矩阵M复制得到T。 TransposeSMatrix(M,&T) 初始条件:稀疏矩阵M已经存在。 操作结果:求稀疏矩阵M的转转矩阵T。 }ADT SparseMatrix 2. 本程序有三个模块: ⑴主程序模块 main(){ 初始化; { 接受命令; 显示结果; }

稀疏矩阵的运算(完美版)

专业课程设计I报告( 2011 / 2012 学年第二学期) 题目稀疏矩阵的转换 专业软件工程 学生姓名张鹏宇 班级学号 09003018 指导教师张卫丰 指导单位计算机学院软件工程系 日期 2012年6月18号

指导教师成绩评定表

附件: 稀疏矩阵的转换 一、课题内容和要求 1.问题描述 设计程序用十字链表实现稀疏矩阵的加、减、乘、转置。 2.需求分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 二、设计思路分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 三、概要设计 为了实现以上功能,可以从3个方面着手设计。 1.主界面设计 为了实现对稀疏矩阵的多种算法功能的管理,首先设计一个含有多个菜单项的主控菜单子程序以链接系统的各项子功能,方便用户交互式使用本系统。本系统主控菜单运行界面如图所示。

2.存储结构设计 本系统采用单链表结构存储稀疏矩阵的具体信息。其中:全部结点的信息用头结点为指针数组的单链表存储。 3.系统功能设计 本系统除了要完成稀疏矩阵的初始化功能外还设置了4个子功能菜单。稀疏矩阵的初始化由函数i typedef int ElemType 实现。建立稀疏矩阵用void Creat()实现,依据读入的行数和列数以及非零元素的个数,分别设定每个非零元素的信息。4个子功能的设计描述如下。 (1)稀疏矩阵的加法: 此功能由函数void Xiangjia( )实现,当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。然后进行加法,最后输出结果。 (2)稀疏矩阵的乘法: 此功能由函数void Xiangcheng( )实现。当用户选择该功能,系统提示输入要进行相乘的两个矩阵的详细信息。然后进行相乘,最后得到结果。 (3)稀疏矩阵的转置: 此功能由函数void Zhuanzhi( )实现。当用户选择该功能,系统提示用户初始

最大子序列和的总结

最大子序列和 第一种情况:可以一个不取 【问题描述】:最大子序列和也叫数列的连续最大和,顾名思义,就是在一个长度为n的数列{An}中,求i,j(1<=i<=j<=n),使得数列{An}中,第i个元素到第j个元素之间,所有元素的和最大。例如:-2, 11, -4, 13, -5, -2时答案为20(11 -4 13) 解法一穷举法:以前我想出了一种算法,具体做法是:取出所给序列的所有子序列求和,共分n组,第一组长度为1,有n个;第二组长度为2, 有n-1个;……,最后一组,长度为n,只有一个。比较这n(n+1)/2个序列的和,再将每组的最大值比较,从而得到最大值以及其上下标。 a1 a2 a n-1 a n a1+a2 a2+a3 a n-1+a n a1+a2+a3 a2+a3+a4 ...... ...... ...... a1+a2......+a n-1 a2+a3......+a n a1+a2......+a n-1 +a n 此算法比较直接,也容易写出代码,但其时间开销为O(n2),空间开销为O(n),效率不高。 解法二:动态规划求解, 1 2 F[i]:表示以元素i结尾的连续最大子序列的和 那么对于第i个元素来说,要形成连续的最大子序列,只和相邻的前一个元素有关。因为可以不取,所以如果元素a[i]连接到以元素i-1结尾的最大连续子序列f[i-1]后是负数(f[i-1]+a[i]<0);则宁可不取,这样最大连续子序列和为0。 动态方程: f[i]:=max{0,f[I-1]+a[i]} (边界条件:f[0]=0;) 3、代码1: for I:=1 to n do if (f[I-1]+a[i])>0 then f[i]:=f[I-1]+a[i] else f[i]:=0; max:=-maxlongint; for i:=1 to n do if f[i]>max then max:=f[i];

稀疏矩阵基本操作实验报告

稀疏矩阵基本操作实验报告 一、实验内容 稀疏矩阵的压缩储存结构,以及稀疏矩阵的三元组表表示方法下的转置、相加、相 乘等算法 二、实验目的 1. 熟悉数组、矩阵的定义和基本操作 2. 熟悉稀疏矩阵的储存方式和基本运算 3. 理解稀疏矩阵的三元组表类型定义,掌握稀疏矩阵的输入、输出和转置算法 三、实验原理 1. 使用三元组储存矩阵中的非零元素(三元组分别储存非零元素的行下标,列下标和 元素值)。除了三元组表本身,储存一个稀疏矩阵还需要额外的三个变量,分别储 存矩阵的非零元个数,矩阵的行数和矩阵的列数。 2. 稀疏矩阵的创建算法: 第一步:根据矩阵创建一个二维数组,表示原始矩阵 第二步:取出二维数组中的元素(从第一个元素开始取),判断取出元素是否为非零元素,如果为非零元素,把该非零元素的数值以及行下标和列下表储存到三元数 组表里,否则取出下一个元素,重复该步骤。 第三步:重复第二步,知道二维数组中所有的元素已经取出。 3. 稀疏矩阵倒置算法:

第一步:判断进行倒置的矩阵是否为空矩阵,如果是,则直接返回错误信息。 第二步:计算要倒置的矩阵每列非零元素的数量,存入到num 数组(其中num[i] 代表矩阵中第i 列非零元素的个数)。以及倒置后矩阵每行首非零元的位置,存入cpot 数组中(其中cpot 表示倒置后矩阵每行非零元的位置,对应表示原矩阵每列中第 一个非零元的位置)。 第三步:确定倒置后矩阵的行数和列数。 第四步:取出表示要导致矩阵中三元组表元素{e, I, j} (第一次取出第一个,依次取出下一个元素),从第二步cpot 数组中确定该元素倒置后存放的位置(cpot[j] ),把该元素的行下标和列下标倒置以后放入新表的指定位置中。cpot[j] 变量加一。 第五步:重复第四步,直到三元组表中所有的元素都完成倒置。 第六步:把完成倒置运算的三元组表输出。 4. 稀疏矩阵加法算法: 第一步:检查相加两个矩阵的行数和列数是否相同,如果相同,则进入第二步,否 则输出错误信息。 第二步:定义变量i 和j,用于控制三元组表的遍历。 第三步:比较变量矩阵M 中第i 个元素和矩阵N 中第j 个元素,如果两个元素是同一行元素,如果不是则进入第四步,如果是,再继续比较两个元素是否为同一列元 素,如果是,把两个元素值相加,放到三元组表中;否则把列下表小的元素依次放 到三元组表中。进入第五步 第四步:如果矩阵M 中第i 个元素的行下标大于矩阵N 中第j 个元素的行下标,则把矩阵N 中第j 个元素所在行的所有非零元素添加到三元组表中;如果矩阵M 中第

第二部分 矩阵的运算符号(1)

2章Matlab及其应用2.1 MATLAB的基本矩阵运算2.2 MATLAB的变量 2.3 关系和逻辑运算 2.4 矩阵操作

2.1、MATLAB的基本矩阵运算2.1.1 简单矩阵输入 1、命令行简单键盘输入 用于很少数据输入 矩阵的方向:, ; NaN Inf 2、文件形式输入 文本文件:从文本文件中读 入数据 mat文件:matlab自有的数 据格式>> B=[1 2 3; 4 5 6] B = 1 2 3 4 5 6

2.1.2 语句生成矩阵 1、线性等间距格式矩阵 (1)X=起始值:增加值:结束值 (2)linspace命令 a=linspace(1,10,5); (3)logspace命令 b=logspace(0,2,10) 2、矩阵连接 c=[a b]; 生成矩阵的函数zeros ones eye randn

2.1.3 矩阵运算1、矩阵的运算符 +:加法 -:減法 *:乘法;点乘:.* /:右除;右除:./ \:左除;左除:.\ ^:乘方 2、矩阵的转置等运算 ’ 共轭转置;.’ 转置 inv:矩阵求逆 det:求行列式值 eig:求特征值与特征向量 1 / () ; \ () : ()*; \ a b a b a b b a Ax b x A b Inv A b x A b - == = === 除法左除法對矩陣

(1)两矩阵加减,前提是维数相同,进行加减运算时,对应的元素进行加减;(2)矩阵与标量加减,用矩阵中的每个元素都与标量进行加减运算; (3)两矩阵相乘,前提是前一矩阵的列等于后一矩阵的行,与数学约定一样;(4)矩阵与标量相乘,用矩阵中的每个元素都与标量进行相乘; (5)矩阵中的元素对元素的相乘:.* 矩阵中的元素对元素的相除:./ .\ z=x.^y x,y均为向量:z(i)=x(i) ^y(i) x为向量,y为标量:z(i)=x(i) ^y x为标量,y为向量:z(i)=x^y(i)

稀疏矩阵数据结构与算法

稀疏矩阵数据结构与算法 §1转置算法 稀疏矩阵在数据结构中不是重点,但是稀疏矩阵既是数据处理的大范围内,又具有一般程序设计与算法结构的基本特征。大学阶段遇到的科学计算类程序不多,稀疏矩阵运算(转置、乘法)的算法是应掌握的起步阶段 算法对运算数据关联范围的设置不同,导致稀疏矩阵的转置算法的效率不同。 一.稀疏矩阵转置程序1的分析

1.什么是转置 M mn-->T nm,其中a ij=b ji (1≤i≤m, 1≤j≤n。i,j可看作与M,T无关的表示,也可以看作矩阵M为主动的下标表示方法),而且a ij∈M, b ji∈T。 矩阵M已知,矩阵T未知。因此在编程时,应考虑以哪个矩阵为算法主序,这是一个出发点。 (1)M,T的行列互换à两个矩阵的行数mu列数nu互换, T.mu=M.nu=n ,T.nu=M.mu=m,以T为主动。 (2)矩阵元素T(i,j)=M(j,i),矩阵T的第i行第j列元素与矩阵M的第j 行第i列元素相等。以T的元素为驱动,因为能从M的元素得到T的元素,所以建立表达式就能得到T元素的值。(在程序中,是否用矩阵T的顺序为算法线索?) 转置矩阵的非0元个数相同,T.tu=M.tu (3)对0元素多的稀疏矩阵的转置而言,与一般矩阵的转置不同。稀疏矩阵的非0元素a ij,在程序中用三元组(i,j,a ij)表示,i,j表示行数列数。因为不再按照矩阵的结构m行n列转置,不使用二维数组作为存储,所以必须记录每一个非0元素所在行列的位置。在规则的二维数组中,矩阵的行列通过元素的下标识别,元素在矩阵中的位置通过下标得到。因

此一般矩阵用二维数组为存储结构。二维数组是物理存储结构的逻辑形式,可称为逻辑存储结构。 2.稀疏矩阵的一维数组存储结构 从操作系统可知,数据的存储方式有三种:连续(顺序)方式,链接方式,索引方式。矩阵不能直接用在计算机中,应选择顺序存储结构二维数组,存放元素。稀疏矩阵的非0元以矩阵行序为序存储在一维数组中,每一行元素的数目不同,可称为非规则数组。 从稀疏矩阵到一维数组是从矩阵结构到以元素次序为主序的逻辑结构变换。稀疏矩阵的一维数组的非0元素是记录(i,j,a ij)。稀疏矩阵三元组表的顺序存储方式,称为三元组顺序表,选用一维数组。三元组表还可用链表表示。 ****这里有两个转换或者两个关系。1.数学表示实体到计算机存储实体的转换。eg.矩阵到一维数组;2.数学逻辑结构到存储逻辑结构的转换。eg.矩阵的行列结构+稀疏矩阵非0元素到一维数组中非0元同行同列+顺序表示的转换。*****注释 数据结构:三元组顺序表 //----稀疏矩阵的三元组表顺序存储表示----// #define MAXSIZE 12500 Typedef struct{

求最大子矩阵及两种思路

求最大子矩阵的两种思路 长沙市雅礼中学贺一骏 编者:求最大子矩阵问题是很常见的一类问题,具有很强的代表性,通过这个问题,可以派生出更加复杂的问题,也可以学到很多常用的问题处理手段。 问题描述 一个被分为 n*m个格子的月饼盒,第 i 行第 j 列位置的格子里面有 a [ i , j ]个月饼。本来CCC老师打算送这盒月饼给某人的,但是就在要送出月饼盒的前一天晚上,一只极其可恶的老鼠夜袭月饼盒,有部分格子被洗劫并且穿了洞。CCC老师必须尽快从这个月饼盒里面切割出一个矩形月饼盒,新的月饼盒不能有洞,并且CCC老师希望保留在新月饼盒内的月饼的总数尽量多。 任务:请帮CCC老师设计一个程序,计算一下新月饼盒最多能够保留多少月饼。 输入 文件的第一行有两个整数 n、m。第 i + 1 行的第 j 个数表示 a [ i , j ],如果这个数为 0 ,则表示这个位置的格子被洗劫过。其中:1 ≤ n,m ≤ 300,0 ≤a [ i , j ]≤ 255 输出 在文件中写入最大月饼数。 样例 Sample Input 3 4 1 2 3 4 5 0 6 3 10 3 4 0 Sample Output 17 分析 该问题实际上是求在给定平面区域中找出一个最大的子矩形,要求该矩形不能包含某些限定的格子。 方法一: 我们初次见到这个问题,可能最直接的想法就是枚举。即枚举每个矩阵的左上角坐标(x1,y1)和右下角坐标(x2,y2),然后统计这个矩阵是否满足题设条件。

我们可以先预处理从左上角(1,1)出发到任意一点(i,j)的月饼数目area(i,j),预处理的时间复杂度为O(mn),程序如下:

稀疏矩阵快速转置 数据结构实验报告

南昌航空大学实验报告 课程名称:数据结构实验名称:实验五稀疏矩阵的存储和快速转置班级:080611 学生姓名:学号:08 指导教师评定:签名: 题目:假设稀疏矩阵A采用三元组表表示,编写程序实现该矩阵的快速转置 要求:输入一个稀疏矩阵A,由程序将其转换成三元组表存储;转置后的三元组表,由程序将其转换成矩阵形式后输出。 一、需求分析 1.用户可以根据自己的需求输入任意一个稀疏矩阵,通过程序将其转换成三元组存储方 式; 2.并且能够完成矩阵的转置功能,要求需要使用的方法是快速转置的方法。 3.最后要够显示原矩阵和转置后的矩阵让用户能进行比较。 4.程序执行的命令包括: (1)构造稀疏矩阵M (2)求转转矩阵T (3)显示(打印)矩阵 二、概要设计 ⒈为实现上述算法,需要线性表的抽象数据类型: ADT SparseMatrix { 数据对象:D={a ij:|a ij∈TermSet,i=1…m,m≥0,j=1…n,n≥0 m和n分别成为矩阵的行数和列数 } 数据关系:R={Row,Col} Row ={|1≤i≤m,1≤j≤n-1 } Col ={|1≤i≤m-1,1≤j≤n } 基本操作: CreateSMtrix(& M) 操作结果:创建稀疏矩阵M。 DestroySMaix(&M) 初始条件:稀疏矩阵M已存在。 操作结果:销毁稀疏矩阵M。 PrintSMatrix(L) 初始条件:稀疏矩阵M已经存在。 操作结果:输出稀疏矩阵M。 CopySMatrix(M,&T) 初始条件:稀疏矩阵M已经存在。 操作结果:由稀疏矩阵M复制得到T。 TransposeSMatrix(M,&T) 初始条件:稀疏矩阵M已经存在。

相关文档
最新文档