最优子矩阵问题

最优子矩阵是建立在数列连续最大和的基础上的。所谓最优子矩阵,就是指在一个n*m二维的矩阵中,确定一个小的矩阵,使这个小矩阵中所有元素的和最大。

思考一下最优子矩阵和连续最大和的异同:

1、  所求的和都具有连续性;

2、  连续最大和是一维问题,最优子矩阵是二维问题

另外,对于一个矩阵而言,如果我们将连续k行的元素纵向相加,并对相加后所得的数列求连续最大和,则此连续最大和就是一个行数为k的最优子矩阵!由此,我们可以将二维的矩阵压缩成一维矩阵,转换为线性问题,从而求解。其实就是将二维的问题,换成一维。

详细参考http://www.cnblogs.com/lyfruit/archive/2013/04/22/3035648.html


#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#define N 4 //matrix N*N

int getrand()

{

int num = rand()%11-5;

return num;

}

void print_matrix(int A[N][N])

{

int i;

int j;

for(i=0;i<N;i++)

{

for(j=0;j<N;j++)

printf("%d\t",A[i][j]);

printf("\n");

}

}

int max_sub_array(int B[], int n)

{

int i = 0;

int sum = 0;

int max = 0;

for(;i<n;i++)

{

sum += B[i];

if(sum>max)

max = sum;

else if(sum<0)

sum = 0;

}

return max;

}

int max_sub_matrix(int A[N][N])

{

int i;

int j;

int k;

int last_i = 0;

int last_j = 0;

int max = 0;

int tmp = 0;

int array[N];

  /*i=0,表示包含第一行的最大子矩阵 i=1...类推*/

for(i=0;i<N;i++)

{

for(k=0;k<N;k++)

array[k] = 0;

for(j=i;j<N;j++)

{

for(k=0;k<N;k++)

array[k] += A[j][k];

tmp = max_sub_array(array, N);

if(tmp>max)

{

last_i = i;

last_j = j;

max = tmp;

}

}

}

/*最大子矩阵开始和结束的行*/

printf("last_i is %d, last_j is %d\n",last_i+1, last_j+1);

return max;

}

int main(int argc, char *argv[])

{

int i;

int j;

int ret;

int A[N][N];

srand((unsigned int)time(NULL));

for(i=0;i<N;i++)

for(j=0;j<N;j++)

A[i][j] = getrand();

print_matrix(A);

ret = max_sub_matrix(A);

printf("max is %d\n",ret);

system("PAUSE");

return 0;

}

时间: 2024-10-07 18:28:04

最优子矩阵问题的相关文章

URAL_1146/uva_108 最大子矩阵 DP 降维

题意很简单,给定一个N*N的大矩阵,求其中数值和最大的子矩阵. 一开始找不到怎么DP,没有最优子结构啊,后来聪哥给了我思路,化成一维,变成最大连续和即可.为了转化成一维,必须枚举子矩阵的宽度,通过预处理的suffix可以很快计算出每一列某一段的和,然后进行一维DP即可..总复杂度为 O(N^3); #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> usi

51nod1158 全是1的最大子矩阵

跟最大子矩阵差不多O(n3)扫一下.有更优写法?挖坑! #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) int read(){ int x=0;ch

动态规划[入门]1- 最大子矩阵和

分析 我们已经解决了一维的问题(基础篇中的最大子段和问题),现在变成二维了,我们看看能不能把这个问题转化为一维的问题.最后子矩阵一定是在某两行之间的.假设我们认为子矩阵在第i行和第j列之间,我们如何得到i和j呢,对,枚举.  枚举所有1<=i<=j<=M,表示最终子矩阵选取的行范围. 我们把每一列第i行到第j行之间的和求出来,形成一个数组c,于是一个第i行到第j行之间的最大子矩阵和对应于这个和数组c的最大子段和.于是,我们的算法变为: for i = 1 to M do for j = 

最大子段和问题,最大子矩阵和问题,最大m子段和问题

1.最大子段和问题      问题定义:对于给定序列a1,a2,a3……an,寻找它的某个连续子段,使得其和最大.如( -2,11,-4,13,-5,-2 )最大子段是{ 11,-4,13 }其和为20. (1)枚举法求解 枚举法思路如下: 以a[0]开始: {a[0]}, {a[0],a[1]},{a[0],a[1],a[2]}……{a[0],a[1],……a[n]}共n个 以a[1]开始: {a[1]}, {a[1],a[2]},{a[1],a[2],a[3]}……{a[1],a[2],……

动态规划 - OJ1768最大子矩阵

题目来源:http://noi.openjudge.cn/ch0206/1768/ 1768:最大子矩阵 总时间限制: 1000ms:内存限制: 65536kB 描述: 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵.比如,如下4 * 4的矩阵 0 -2 -7 09 2 -6 2-4 1 -4 1-1 8 0 -2 的最大子矩阵是 9 2-4 1-1 8 这个子矩阵的大小是15. 输入: 输入是一个N * N的矩阵.输入的第一行给出N

JVM原理讲解和调优

一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的. Java语言的一个非常重要的特点就是与平台的无关性.而使用Java虚拟机是实现这一特点的关键.一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码.而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译.Java语言使用Java虚拟机屏蔽了与具体平台相关的信息

爱奇艺、优酷、腾讯视频竞品分析报告2016(一)

1 背景 1.1 行业背景 1.1.1 移动端网民规模过半,使用时长份额超PC端 2016年1月22日,中国互联网络信息中心 (CNNIC)发布第37次<中国互联网络发展状况统计报告>,报告显示,网民的上网设备正在向手机端集中,手机成为拉动网民规模增长的主要因素.截至2015年12月,我国手机网民规模达6.20亿,有90.1%的网民通过手机上网. 图 1  2013Q1~2015Q3在线视频移动端和PC端有效使用时长份额对比 根据艾瑞网民行为监测系统iUserTracker及mUserTrac

WordPress解决优酷、土豆视频移动端观看问题并自适应

转:https://www.xhsay.com/wp-iframe-handler-youku-tudou.html 虽然WordPress能直接插入优酷.土豆的视频但是无法在移动端观看,于是乎笨笨就开始各种折腾终于找到了合适的解决办法另外在说一句支持移动端自适应哦. 函数代码 在主题函数文件function.php里面添加以下代码即可,保证在最后一个?>之前就好了 //Youku function wp_iframe_handler_youku($matches, $attr, $url, $

spark性能调优之资源调优

转https://tech.meituan.com/spark-tuning-basic.html spark作业原理 使用spark-submit提交一个Spark作业之后,这个作业就会启动一个对应的Driver进程.根据你使用的部署模式(deploy-mode)不同,Driver进程可能在本地启动,也可能在集群中某个工作节点上启动.Driver进程本身会根据我们设置的参数,占有一定数量的内存和CPU core.而Driver进程要做的第一件事情,就是向集群管理器(可以是Spark Stand