题目大意:

在一个给定的大矩阵中找一个小型的矩阵,使这个矩阵中的元素和最大

可以先来看下面这个问题:

  原来有做过在一个给定的数字序列中找一个最大和子序列,核心代码如下:

   

         int _max = num[];
int sum = num[];
int st = ;
int la = ;
int rec;
for(int i = ; i<k ; i++){
if(sum < ){
rec = i;//记录起点
sum = ;
}
sum += num[i];
if(sum > _max){
_max = sum;
st = rec;
la = i;
}
}

当然如果只是求最大值,可以不用st , la,这是用来记录找到的序列的端点位置的

明显这个问题和找最大和矩阵有着共通点,这个找子序列可以看作是一维的,而找矩阵,矩阵上的点也是相互紧连的,那也就是可以看作是在二维的平面上找

这里需要把一维的转化为二维的是关键

我们可以假定把每一行看作单个的元素,知道每个元素的值,那我们就能够将n列,看作有n个这样的压缩元素,那我们就是在这n个元素中找最大值

(当然压缩列也是可以的,这里我的代码写的是压缩行)

我们需要找到所有情况,因为所求矩阵不一定端点就在大矩阵的两端,也可以是中间,这里N <= 100 , N表示边, 那么上面的点至少有101个 , 所以我们

至少需要对每一行有101*101个这样的压缩情况,另外我们需要知道每一行压缩101*101种情况后的值那么至少要101*101*100的空间来保存

显然不太合理,当然我本人没试过,按理觉得也不会MLE

那么我们转化成用二维的sum[i][j]保存,表示第i行前j个数的和

那么比如我们得到第k行压缩第5个点和第99个点中间得到的大小为94的矩阵长度为一个元素

那么它的值就为 sum[k][99] - sum[k][5]

压缩好后就是简单的在线性时间内解决最大和子序列的问题了

 #include <cstdio>
#include <cstring> using namespace std;
const int N = ;
int num[N][N] , sum[N][N]; int main()
{
// freopen("a.in" , "r" , stdin);
int n , maxn;
while(~scanf("%d" , &n)){
memset(sum , , sizeof(sum)); for(int i = ; i<n ; i++)
for(int j = ; j<n ; j++){
scanf("%d" , &num[i][j]);
sum[i][j+] = num[i][j] + sum[i][j];
} maxn = ;
for(int i = ; i<=n ; i++)
for(int j = ; j<i ; j++)
{
int suma = ;
for(int k = ; k<n ; k++)//从第i行不断往下在i到j列找到某一段矩阵得到最大值
{
if(suma<)
suma = ; suma += (sum[k][i] - sum[k][j]);
if(suma > maxn)
maxn = suma;
}
} printf("%d\n" , maxn);
}
return ;
}

HDU 1081 DP找最大和的矩阵的更多相关文章

  1. hdu 1081 dp问题:最大子矩阵和

    题目链接 题意:给你一个n*n矩阵,求这个矩阵的最大子矩阵和 #include<iostream> #include<cstdio> #include<string.h& ...

  2. HDU 1081 To The Max【dp,思维】

    HDU 1081 题意:给定二维矩阵,求数组的子矩阵的元素和最大是多少. 题解:这个相当于求最大连续子序列和的加强版,把一维变成了二维. 先看看一维怎么办的: int getsum() { ; int ...

  3. hdu 1081 To The Max(dp+化二维为一维)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1081 To The Max Time Limit: 2000/1000 MS (Java/Others ...

  4. hdu 1081 To The Max(二维压缩的最大连续序列)(最大矩阵和)

    Problem Description Given a two-dimensional array of positive and negative integers, a sub-rectangle ...

  5. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  6. HDU 5928 DP 凸包graham

    给出点集,和不大于L长的绳子,问能包裹住的最多点数. 考虑每个点都作为左下角的起点跑一遍极角序求凸包,求的过程中用DP记录当前以j为当前末端为结束的的最小长度,其中一维作为背包的是凸包内侧点的数量.也 ...

  7. [FJOI2007]轮状病毒 题解(dp(找规律)+高精度)

    [FJOI2007]轮状病毒 题解(dp(找规律)+高精度) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1335733 没什么好说的,直接把规律找出来,有 ...

  8. hdu 2604 Queuing dp找规律 然后矩阵快速幂。坑!!

    http://acm.hdu.edu.cn/showproblem.php?pid=2604 这题居然O(9 * L)的dp过不了,TLE,  更重要的是找出规律后,O(n)递推也过不了,TLE,一定 ...

  9. (DP)To The Max --HDU -- 1081

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1081 这道题使用到的算法是:预处理+最大连续子串和 如果会做最大连续子串和,那么理解这题就相对简单一些, ...

随机推荐

  1. bzoj 1671: [Usaco2005 Dec]Knights of Ni 骑士【bfs】

    bfs预处理出每个点s和t的距离d1和d2(无法到达标为inf),然后在若干灌木丛格子(x,y)里取min(d1[x][y]+d2[x][y]) /* 0:贝茜可以通过的空地 1:由于各种原因而不可通 ...

  2. Linux学习笔记之Linux系统启动过程

    Linux系统的启动过程可以分为五个阶段: 内核的引导 运行init 系统初始化 建立终端 用户登录系统 1.内核引导: 当计算机打开电源后,首先进行BIOS开机自检,按照BIOS中设置的启动设备(一 ...

  3. 震惊!double输入输出的秘密竟然是~

    遇到了一个神奇的事情: double r = 3.0; printf("%lf", r);//0.000000 double遇到printf函数竟然是用%f输出的! scanf函数 ...

  4. log4j2异步日志解读(一)AsyncAppender

    log4j.logback.log4j2 历史和关系,我们就在这里不展开讲了.直接上干货,log4j2突出于其他日志的优势,异步日志实现. 看一个东西,首先看官网文档 ,因为前面文章已经讲解了disr ...

  5. 6.12---bug

  6. Ubuntu下查看服务器cpu是否支持VT

    http://blog.51cto.com/zhangmingqian/1249522 Ubuntu下查看服务器cpu是否支持VT 原创wazjajl 2013-07-15 16:25评论(0)119 ...

  7. 在中间层 .NET 应用程序中通过授权管理器使用基于角色的安全

    基于角色的安全是从 Windows NT 的第一个版本开始在 Windows 平台上发展而来的.使用角色,操作系统可以通过检查称为 BUILTIN\Administrators 的组的安全上下文做出一 ...

  8. VMWare虚拟机中Ubuntu 16.04 (linux无桌面)配置静态IP上网

    1. 基础环境说明 虚拟机: VMWare 12.5.2 操作系统: Ubuntu 16.04 (无桌面) 物理主机操作系统: win 7 旗舰版 2. 摸底 VMware在安装之后,会创建2个虚拟的 ...

  9. SQL函数-汉字首字母查询

    汉字首字母查询处理用户定义函数 CREATE FUNCTION f_GetPY1(@str nvarchar(4000))RETURNS nvarchar(4000)ASBEGIN DECLARE @ ...

  10. 使用WAS寄宿net.tcp WCF服務

    首先添加Windows Features 確保打開以下服務 Net.Tcp Listener Adapter Net.Tcp Port Sharing Service Windows Process ...