HDU 1081 DP找最大和的矩阵

题目大意:

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

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

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

   

 1         int _max = num[0];
 2         int sum = num[0];
 3         int st = 0;
 4         int la = 0;
 5         int rec;
 6         for(int i = 1 ; i<k ; i++){
 7             if(sum < 0){
 8                 rec = i;//记录起点
 9                 sum = 0;
10             }
11             sum += num[i];
12             if(sum > _max){
13                 _max = sum;
14                 st = rec;
15                 la = i;
16             }
17         }

当然如果只是求最大值,可以不用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]

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

 1 #include <cstdio>
 2 #include <cstring>
 3
 4 using namespace std;
 5 const int N = 105;
 6 int num[N][N] , sum[N][N];
 7
 8 int main()
 9 {
10   //  freopen("a.in" , "r" , stdin);
11     int n , maxn;
12     while(~scanf("%d" , &n)){
13         memset(sum , 0 , sizeof(sum));
14
15         for(int i = 0 ; i<n ; i++)
16             for(int j = 0 ; j<n ; j++){
17                 scanf("%d" , &num[i][j]);
18                 sum[i][j+1] = num[i][j] + sum[i][j];
19             }
20
21         maxn = 0;
22         for(int i = 0 ; i<=n ; i++)
23             for(int j = 0 ; j<i ; j++)
24             {
25                 int suma = 0;
26                 for(int k = 0 ; k<n ; k++)//从第i行不断往下在i到j列找到某一段矩阵得到最大值
27                 {
28                     if(suma<0)
29                         suma = 0;
30
31                     suma += (sum[k][i] - sum[k][j]);
32                     if(suma > maxn)
33                         maxn = suma;
34                 }
35             }
36
37         printf("%d\n" , maxn);
38     }
39     return 0;
40 }
时间: 2024-10-19 21:28:41

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

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

题目链接 题意:给你一个n*n矩阵,求这个矩阵的最大子矩阵和 #include<iostream> #include<cstdio> #include<string.h> using namespace std; #define inf -0x3f3f3f3f int field[105][105],dp[105]; int main() { int n; while(~scanf("%d",&n)) { int maxn=0; memset

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)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8839    Accepted Submission(s): 4281 Problem Description Given a two-dimensional ar

hdu 1081 &amp; poj 1050 To The Max(最大和的子矩阵)

转载请注明出处:http://blog.csdn.net/u012860063 Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum

hdu 1081最大子矩阵的和DP

To The Max Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8210    Accepted Submission(s): 3991 Problem Description Given a two-dimensional array of positive and negative integers, a sub-rectan

HDU 1081 To The Max(DP)

题意  求一个n*n矩阵的最大子矩阵和 HDU 1003 max sum 的升级版   把二维简化为一维就可以用1003的方法去做了  用mat[i][j]存  第i行前j个数的和   那么mat[k][j]-mat[k][i]就表示第k行  第i+1个数到第j个数的和了   再将k从一枚举到n就可以得到这个这个宽度为j-i的最大矩阵和了   然后i,j又分别从1枚举到n就能得到结果了   和1003的方法一样  只是多了两层循环 #include<cstdio> #include<cs

HDU 1081 To The Max--DP--(最大子矩阵)

题意:输入一个二维数组,求和最大的子矩阵 分析:一看到和最大的子XX,我就联想到和最大子序列,只不过那是一维这是二维,所以做法都差不多.把二维压缩成一维:你想啊一个矩阵的和不是可以先垂直方向相加把所有行压缩为一行然后这一行相加嘛.压缩过后找最大和的方法跟一维一模一样.但我自己做的时候写了四个循环,唉.....数组可以存放之前求过的和,那么求以下一行为结尾的和的时候只要在原来的数组上加这一行的数就行了,不需要从头循环求和! dp[k]=a[i][k]+.....+a[j][k] 第 k 列第 i

HDU 1003 &amp;&amp; HDU 1081(最大子列和,最大子矩阵和).

最大子列和,及其扩展最大子矩阵和,都是比较经典的dp,把这两题写在一起,共大家参考学习. ~~~~ lz弱菜啊,到现在还只能写这么水的DP...orz. ~~~~ 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 http://acm.hdu.edu.cn/showproblem.php?pid=1081 题意应该比较好理解,不解释了. 1003: #include<cstdio> #include<iostream> #inc

HDU 4772 Zhuge Liang&#39;s Password 选择矩阵

本题需要使用选择矩阵的程序求解,这个和Leetcode上的一个程序是一样道理的.如果使用额外空间,那么是很容易做到的,这里不使用额外空间,直接使用到位操作,空间效率是O(1),这是个非常漂亮的到位旋转程序. 题意还是很重要,这次看错了一句话,就WA了一次: The maximum amount of cells which contains two equal numbers after overlapping, is the password. 这里是需要每次旋转之后求相同数字的最大值,而不是

hdu 1757 A Simple Math Problem (乘法矩阵)

A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2441    Accepted Submission(s): 1415 Problem Description Lele now is thinking about a simple function f(x).If x < 10 f(x) =