题解+新技巧--一本通1282:最大子矩阵

http://ybt.ssoier.cn:8088/problem_show.php?pid=1282(题目传送)

虽然已知是DP,但第一眼看挺蒙的,想了想后设了个a[i][j][k][l]表示长(坐标)为i~j,宽(坐标)为k~l的矩阵,但根本找不到状态转移方程啊。后借鉴题解(https://www.cnblogs.com/GodA/p/5237061.html)后领悟到的另一种方法:

任何问题都有它的简化,看到二维,没办法时我们可以考虑一下一维:求一维数组的一个最大连续段,我们可以设b[i]为从前i个数的最大连续段(a[i]为一开始存入的输入数据),b[i]无非就有两种情况:以它结尾的最大连续段;或以它开头另开一个最大连续段(当b[i-1]小于0时b[i-1]+a[i]反而比a[i]小,因此不如新开一个最大连续段)。

 1 int MaxSubArray(int a[],int n)
 2 {
 3     int i,b = 0,sum = 0;
 4     for(i = 0;i < n;i++)
 5     {
 6         if(b>0)                // 若a[i]+b[i-1]会减小
 7             b += a[i];        // 则以a[i]为首另起一个子段
 8         else
 9             b = a[i];
10         if(b > sum)
11             sum = b;
12     }
13     return sum;
14 }

想完一维,跟二维有什么关系?当然有了,我们把二维“拍”成一维,不就行了吗?

我们假设所求N*N的矩阵的最大子矩阵是从i列到j列,q行到p行,如下图所示(假设下标从1开始)

  a[1][1]  a[1][2]  ······  a[1][i]  ······  a[1][j]   ······  a[1][n]

  a[2][1]  a[2][2]  ······  a[2][i]  ······  a[2][j]   ······  a[2][n]

                  ······

  a[q][1]  a[q][2]  ······  a[q][i]  ······  a[q][j]  ······  a[q][n]

                  ······

  a[p][1]  a[p][2]  ······  a[p][i]  ······  a[p][j]  ······  a[p][n]

                  ······

  a[n][1]  a[n][2]  ······  a[n][i]  ······  a[n][j]  ······  a[n][n]

  最大子矩阵就是图示红色部分,如果把最大子矩阵同列的加起来,我们可以得到一个一维数组{a[q][i]+······+a[p][i] , ······ ,a[q][j]+······+a[p][j]} ,现在我们可以看出,这其实就是一个一维数组的最大子段问题:

分别将各个高的矩阵压缩成一个一维数组并求它的最大连续段,则在二维的体现就是一个相应高的最大连续矩阵,取所有相应最大连续矩阵的最大值,就是答案(还好题目只要求最大值,不要求给出最大矩阵是什么)

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int dp[101][101],arr[101];
 6 int maxsub(int a[],int n)
 7 {
 8     int max=0,b=0;
 9     for(int i=0;i<=n;i++)
10     {
11         if(b>0)
12             b+=a[i];
13         else
14             b=a[i];
15         if(b>max) max=b;
16     }
17     return max;
18 }
19 int main()
20 {
21     int n,maxx=0;
22     cin>>n;
23     for(int i=1;i<=n;i++)
24         for(int j=1;j<=n;j++)
25             cin>>dp[i][j];
26     for(int i=1;i<=n;i++)
27     {
28         memset(arr,0,sizeof(arr));
29         for(int j=i;j<=n;j++)
30         {
31             for(int k=1;k<=n;k++)
32             arr[k]+=dp[j][k];
33             int m=maxsub(arr,n);
34             if(maxx<m)
35             maxx=m;
36         }
37     }
38     cout<<maxx;
39     return 0;
40 }

最后总结一下:1.对问题的简化(二维转一维,模拟转整体充分条件(长方体),无序转有序等)十分重要!

2.线型动态规划多以结尾为状态。

原文地址:https://www.cnblogs.com/InductiveSorting-QYF/p/10503140.html

时间: 2024-10-17 19:09:12

题解+新技巧--一本通1282:最大子矩阵的相关文章

写互联网文案的新技巧

新媒体的崛起,互联网信息时代的到来,都为企业和品牌的推广文案创造了更多的可能.一本正经阐述产品功能的文案,早就已经被我们自动过滤掉了. 试问现在,在昏昏欲睡的公交车厢上,你是愿意看一篇中规中矩的广告文案,还是愿意你看一段自黑卖萌的逗趣品牌文案,答案当然是后者. 写互联网文案的新技巧:自黑远比自夸强 2013年天猫在双十一推送了一条数据计算失误的微博,进而被网友群嘲.次日天猫及时做出了回复,博文为:伦家就是激动的昏头了好吗.....来尽尽尽尽情取笑我吧!数学老师对不起了!轻松诙谐的态度赢得了众多网

Sketch实用新技巧详解

作为目前产品原型设计中的利器,Sketch特别适合移动APP和响应式网页的设计开发.下面我们就来看看Sketch的一些入门指南以及如何利用Mockplus的插件实现交互效果. Sketch是一款基于Mac的矢量绘图应用.面对着功能复杂繁琐的photoshop,Sketch相比较而言身轻如燕.最近也掀起了用Sketch设计产品原型的热潮,因为用它来画设计稿简直轻而易举,相比于Axure它有更丰富的组件库和更全面的尺寸控制,让我们的原型图更逼真,更有利于交流和前期的展示. 作为目前产品原型设计中的利

打开cmd窗口新技巧get

1.在当前目录下,按住shift键+点击右键,选择在此处打开命令窗口 很多时候我们需要打开命令行然后进入到相应目录进行一些操作. 常规的做法是: Win+R打开运行窗口 输入"cmd"回车打开命令行窗口 假如我们要进入的是D盘foo文件夹下的一个bar子文件夹,路径是这样的D:\foo\bar,首先输入" D:"回车进入D盘 再依次输入"cd foo"," cd bar"; 或者在资源管理器的地址栏里复制文件夹地址"

HDU 3415 Max Sum of Max-K-sub-sequence 单调队列题解

本题又是一题单调队列题解. 技巧就是需要计算好前n项和Sn = a1 + a2 + ... an 这样方便处理. 记录一条单调队列,其意义是: q(head), q(head+1), ...q(tail) 其中头q(head)代表当前最佳解的起点 这样我们只需要在求某点为结尾的S[i] - S[q(head)就得到当前最佳值. 了解了单调数列,知道其中的记录意义,那么这道题就没有难度了.我也是了解这些信息之后就自己敲出代码的. 不过有些细节没写好也让我WA了几次. 最近少刷水题,而一直都是每天一

巧用React Fiber中的渲染字符串新功能

虽然React Fiber还没有正式发布,但是我们已经可以预先领教其带来的新的编程模式了. 在React Fiber中,render函数可以直接返回一个字符串了,换言之,一个组件可以直接渲染为一个字符串,而不是必须渲染为一个HTML模样的物体. 举个例子,下面这个控件LongString,显示一个input和一个p,p中文字可以是很长的字符串,相当于一个模板,在input中输入的字符串会用来填补p中的模板面. 代码如下. import React from 'react'; class Long

&lt;转&gt; 30 个有关 Python 的小技巧

目录[+] 1.1 拆箱 1.2 拆箱变量交换 1.3 扩展拆箱(只兼容python3) 1.4 负数索引 1.5 切割列表 1.6 负数索引切割列表 1.7指定步长切割列表 1.8 负数步长切割列表 1.9 列表切割赋值 1.10 命名列表切割方式 1.11 列表以及迭代器的压缩和解压缩 1.12 列表相邻元素压缩器 1.13 在列表中用压缩器和迭代器滑动取值窗口 1.14 用压缩器反转字典 1.15 列表展开 1.16 生成器表达式 1.17 字典推导 1.18 用字典推导反转字典 1.19

实用技巧:如何用 CSS 做到完全垂直居中

本文将教你一个很有用的技巧——如何使用 CSS 做到完全的垂直居中.我们都知道 margin:0 auto; 的样式能让元素水平居中,而 margin: auto; 却不能做到垂直居中……直到现在.但是,请注意!想让元素绝对居中,只需要声明元素高度,并且附加以下样式,就可以做到: 1 2 3 4 5 .Absolute-Center {   margin: auto;   position: absolute;   top: 0; left: 0; bottom: 0; right: 0; }

30个有关Python的小技巧

从我开始学习python的时候,我就开始自己总结一个python小技巧的集合.后来当我什么时候在Stack Overflow或者在某个开源软件里看到一段很酷代码的时候,我就很惊讶:原来还能这么做!,当时我会努力的自己尝试一下这段代码,直到我懂了它的整体思路以后,我就把这段代码加到我的集合里.这篇博客其实就是这个集合整理后一部分的公开亮相.如果你已经是个python大牛,那么基本上你应该知道这里面的大多数用法了,但我想你应该也能发现一些你不知道的新技巧.而如果你之前是一个c,c++,java的程序

35个Python编程小技巧

转自:http://www.jb51.net/article/48595.htm 从我开始学习python的时候,我就开始自己总结一个python小技巧的集合.后来当我什么时候在Stack Overflow或者在某个开源软件里看到一段很酷代码的时候,我就很惊讶:原来还能这么做!,当时我会努力的自己尝试一下这段代码,直到我懂了它的整体思路以后,我就把这段代码加到我的集合里. 这篇博客其实就是这个集合整理后一部分的公开亮相.如果你已经是个python大牛,那么基本上你应该知道这里面的大多数用法了,但