dp例题03. 最大子矩阵和
题目Description:
给出一个矩阵, 求子矩阵(可以是其本身)数之和的最大值
Input:
第一行 为行数n和列数m (n≤500, m≤500)
接下来为一个n行m列的矩阵 (每个值ai,−1000 ≤ ai ≤ 1000)
Output:
子矩阵(可以是其本身)数之和的最大值
Sample Input:
4 4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
Sample Output:
15
解题思路:
解法1:单纯用二维前缀和 时间复杂度O(n*n*m*m);(TLE)
解法2:dp+前缀和 时间复杂度O(n*n*m) 或O(n*m*m)
如果是求一维的最长子序列 我们会用O(n)的时间复杂度求出
而这里为二维的, 能否用一维的解法思想去转化一下?
刚开始从行数遍历(不裁剪列数情况下)所有的子矩阵, 需要O(n²)时间, 之后对于这样遍历的子矩阵进行求解最大和,能否利用O(m)时间完成求解
遍历后的二维子矩阵可以一维数组化(即 将 单列上的数相加为一个数, 构造出plus数组), 再利用求一维最长子序列的思想(O(m)时间复杂度)即可
构造plus数组:利用每一列上的前缀和, 比如求第 k 列上第 i 行到第 j 行的数之和 plus[k] = col_sum[j][k] - col_sum[i-1][k]; O(1) 时间复杂度
单独构造col_sum数组: O(n*m)时间复杂度
以下为c语言代码(解法2)
#include <stdio.h>
int a[][], col_sum[][];
int max_subsequence(int * a, int n) {
int sum = -1e7, max = -1e7;
for (int i = ; i < n; i++) {
sum = (sum + a[i] > a[i])? sum + a[i] : a[i];
max = (sum > max)? sum : max;
}
return max;
}
int main() {
int row, col, plus[];
scanf("%d%d", &row, &col);
for (int i = ; i < row; i++) {
for (int j = ; j < col; j++) {
scanf("%d", &a[i][j]);
}
}
for (int j = ; j < col; j++) {
for (int i = ; i < row; i++) {
if (i == ) {
col_sum[i][j] = a[i][j];
}
else {
col_sum[i][j] = col_sum[i-][j] + a[i][j];
}
}
}
int ans = -1e7;
for (int i = ; i < row; i++) {
for (int k = i; k < row; k++) {
if (i == ) {
for (int j = ; j < col; j++) {
plus[j] = col_sum[k][j];
}
int temp = max_subsequence(plus, col);
ans = (temp > ans) ? temp : ans;
}
else {
for (int j = ; j < col; j++) {
plus[j] = col_sum[k][j] - col_sum[i-][j];
}
int temp = max_subsequence(plus, col);
ans = (temp > ans) ? temp : ans;
}
}
}
printf("%d\n", ans);
return ;
}
dp例题03. 最大子矩阵和的更多相关文章
- hdu 1081 dp问题:最大子矩阵和
题目链接 题意:给你一个n*n矩阵,求这个矩阵的最大子矩阵和 #include<iostream> #include<cstdio> #include<string.h& ...
- 基础dp例题整理
背包: 消失之物 先直接做一遍,必然对于i,有 for(j=m;j>=w[i];--j) f[i]+=f[i-w[i]] 所以,如果排除用i做背包的结果,减去这个转移就好了. memcpy(g, ...
- [hdu 4734]数位dp例题
通过这个题目更加深入了解到了数位dp在记忆化搜索的过程中就是实现了没有限制条件的n位数的状态复用. #include<bits/stdc++.h> using namespace std; ...
- 大白第一章第四节dp例题
入口 UVALive - 3882 #include<cstdio> using namespace std; ; int n,m,k,f[N]; int main(){ //f[i]表示 ...
- dp例题02. 滑雪问题 (poj1088)
poj1088滑雪问题 题目链接:http://poj.org/status Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得 ...
- dp例题01. 任务价值最大化
题目Description: 大凯有n项任务可选择去做, 分别对应有开始时间, 结束时间以及任务报酬, 同一时间内最多做一件任务, 现在大凯想知道最多能得到多少报酬, 于是把求解任务交给了你. 输入: ...
- 区间dp 例题
D - 石子合并问题--直线版 HRBUST - 1818 这个题目是一个区间dp的入门,写完这个题目对于区间dp有那么一点点的感觉,不过还是不太会. 注意这个区间dp的定义 dp[i][j] 表示的 ...
- NOI题库 1768最大子矩阵 题解
NOI题库 1768最大子矩阵 题解 总时间限制: 1000ms 内存限制: 65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大 ...
- LightOJ1033 Generating Palindromes(区间DP/LCS)
题目要计算一个字符串最少添加几个字符使其成为回文串. 一年多前,我LCS这道经典DP例题看得还一知半解时遇到一样的问题,http://acm.fafu.edu.cn/problem.php?id=10 ...
随机推荐
- LeetCode 33,在不满足二分的数组内使用二分的方法
本文始发于个人公众号:TechFlow,原创不易,求个关注 链接 Search in Rotated Sorted Array 难度 Medium 描述 给定一个升序排列的数组,它被分成两部分之后交换 ...
- 必备技能三、render渲染函数
Vue 推荐使用在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template ...
- Block详解一(底层分析)
本篇博客不再讲述Block的基本定义使用,最近而是看了很多的block博客讲述的太乱太杂,所以抽出时间整理下block的相关底层知识,在讲述之前,提出几个问题,如果都可以回答出来以及知道原理,大神绕过 ...
- [POI2017]bzoj4726 Sadota?
题目描述 离线题库请 题目描述 某个公司有\(n\)个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属(直接或者间接, 不包括他自己)中叛徒占的比例超 ...
- try_catch_return
1.情况一(try中有return,finally中没有return): public class TryTest{ public static void main(String[] args){ S ...
- foobox,基于foobar2000汉化版的CUI配置整合版
名 称:foobox 作 者:dreamawake 发布博客:https://www.cnblogs.com/foobox/ GitHub: https://github.com/dream7180/ ...
- Python基础 | 日期时间操作
目录 获取时间 时间映射 格式转换 字符串转日期 日期转字符串 unixtime 时间计算 时间偏移 时间差 "日期时间数据"作为三大基础数据类型之一,在数据分析中会经常遇到. 本 ...
- 强连通分量SCC 2-SAT
强连通分量SCC 2-SAT 部分资料来自: 1.https://blog.csdn.net/whereisherofrom/article/details/79417926 2.https://ba ...
- 【转】Java包管理器Maven学习
Maven 引入Jar包的几种情况 1.通过pom.xml中导入的jar包 (1)链接打开http://mvnrepository.com/ (2)搜索罐包,比如我想要的是servlet的api.ja ...
- Django之模板层细说
django的模板层,基于我们前面学习的内容,也知道主要语法是{{变量相关}}{%逻辑相关%},那么具体还有哪些内容呢?且听我娓娓道来. 模板层(模板语法) 标签 过滤器 自定义标签,过滤器,incl ...