HDU1081:To The Max(最大子矩阵,线性DP)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1081

自己真够垃圾的,明明做过一维的这种题,但遇到二维的这种题目,竟然不会了,我也是服了(ps:猪啊)。

最终还是看了题解。

代码如下:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int n,w[110][110],t;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(w,0,sizeof(w));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
               scanf("%d",&t);
               w[i][j]+=w[i][j-1]+t;
            }
        }
        int maxx=-inf;
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            {
                int sum=0;
                for(int k=1;k<=n;k++)
                {
                    if(sum<0) sum=0;
                    sum+=w[k][j]-w[k][i-1];
                     if(sum>maxx)
                        maxx=sum;
                }
            }
        }
        printf("%d\n",maxx);
    }
    return 0;
}

大神的题解:

这一题就是将一维的最大字段和扩展到二维,在一维的求最大字段和的过程中是这样操作的:

int max_sum(int n)
{
    int i, j, sum = 0, max = -10000;
    for(i = 1; i <= n; i++)
    {
        if(sum < 0)
            sum = 0;
        sum += a[i];
        if(sum > max)
            max = sum;
    }
    return sum;
}
扩展到二维的时候也是同样的方法,不过需要将二维压缩成一维,所以我们要将数据做一下处理,使得map[i][j]从表示第i行第j个元素变成表示第i行前j个元素和,这样map[k][j]-map[k][i]就可以表示第k行从i->j列的元素和。只要比一维多两层循环枚举i和j就行了。
#include <iostream>
#define MAX 101
using namespace std;
int map[MAX][MAX];
int main()
{
    int n, i, j, temp, k;

    while(scanf("%d", &n) != EOF)
    {
        memset(map, 0, sizeof(map));
        for(i = 1; i <= n; i++)
            for(j = 1; j <= n; j++)
            {
                scanf("%d", &temp);
                map[i][j] += map[i][j - 1] + temp;//这里表示第i行的前j列之和
            }
        int max = -100000;
        for(i = 1; i <= n; i++)
            for(j = i; j <= n; j++)
            {
                int sum = 0;
                for(k = 1; k <= n; k++)
                {
                    if(sum < 0)
                        sum = 0;
                    sum += map[k][j] - map[k][i  - 1];//这里表示前k行,i->j列之和
                    if(sum > max)
                        max = sum;
                }
            }
        printf("%d\n", max);
    }
return 0;
}
时间: 2024-10-06 00:54:11

HDU1081:To The Max(最大子矩阵,线性DP)的相关文章

HDU1081 To The Max 最大子矩阵和

题意:求最大子矩阵和. 解题思路:枚举上下边界 ,用一维思路去搞. 解题代码: 1 // File Name: 1081.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月01日 星期三 16时57分14秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #

poj 1050 To the Max(线性dp)

题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而最大子矩阵为二维问题, 可以考虑将二维问题转换为一维问题,即变为最大子段和问题即可求解: 先考虑暴力解法,暴力解法需要枚举子矩阵的左上角元素的坐标与子矩阵的右下角坐标即可枚举所有的子矩阵:对于每个子矩阵,考虑压缩子矩阵的每一列 元素,即求每一列的元素的和,这样子矩阵就转换为一维的情况,再使用最大子段

HDU 5074 Hatsune Miku (线性dp)

Hatsune Miku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 471 Problem Description Hatsune Miku is a popular virtual singer. It is very popular in both Japan

poj2533——lis(最长上升子序列), 线性dp

poj2533——lis(最长上升子序列), 线性dp Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36143   Accepted: 15876 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given n

动态规划——线性dp

我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模型,例如最长上升子序列(LIS).最长公共子序列(LCS).最大子序列和等,那么首先我们从这几个经典的问题出发开始对线性dp的探索. 首先我们来看最长上升子序列问题. 这个问题基于这样一个背景,对于含有n个元素的集合S = {a1.a2.a3……an},对于S的一个子序列S‘ = {ai,aj,ak

POJ 1163 The Triangle (简单线性dp)

OJ题目 : click here~~ 题目分析:给一个数字三角形,从最上面一个数字开始,方向只能往左下或者右下,一直到最后一行,求经过的所有数字和的最大值. 搞清楚在输入的数据中,route的方向就行. AC_CODE int num[102][102]; int main(){ int n , i , j , k ; while(cin >> n){ int x[102][102]; for(i = 1;i <= n;i++) for(j = 1;j <= i;j++) sca

POJ 2479-Maximum sum(线性dp)

Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33918   Accepted: 10504 Description Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below: Your task is to calculate d(A). Input The input consists o

HDU 4293 Groups (线性dp)

OJ题目:click here~~ 题目分析:n个人分为若干组 , 每一个人描写叙述其所在的组前面的人数和后面的人数.求这n个描写叙述中,最多正确的个数. 设dp[ i ] 为前i个人的描写叙述中最多正确的个数,则dp[ n ] 为要求的.num[ i ][ j ]  保存说前面有i个人 , 后面有j个人的人数,显然num[ i ][ j ]不超过n - i - j; 转移方程dp[ i ] = max(dp[ i ] , dp[ j ]  + num[ j ][ n - i ])  ,详解见代

POJ 1157 LITTLE SHOP OF FLOWERS (线性dp)

OJ题目:click here~~ 题目分析:f个束花,编号为1-- f.v个花瓶,编号为1 -- v.编号小的花束,所选花瓶的编号也必须比编号大的花束所选花瓶的编号小,即花i 选k, 花j选t ,如果i < j ,则定有k < t . 如果 i > j , 则定有 k > t . 每束花放在每个花瓶里有一个值.求f束花,能得到的最大值. 设dp[ i ][ j ] 为第 i 束花选择了第 j 个花瓶 , 则转移方程为 dp[ i ][ j ] =  max(dp[ i  - 1]

poj2279 Mr. Young&#39;s Picture Permutations[勾长公式 or 线性DP]

若干人左对齐站成最多5行,给定每行站多少个,列数从第一排开始往后递减.要求身高从每排从左到右递增(我将题意篡改了便于理解233),每列从前向后递增.每个人身高为1...n(n<=30)中的一个数(互不不同).求可行方案数.(地址点我qwq): 做了lyd书dp这一章的第一题,就不会qwq..果然菜的人还是永远菜啊,注定翻不了身. lyd的书上讲到了dp的方法,不是很理解.后来想通了,发现自己想的时候也想到了这一点转化,但是又很快把他抛弃掉了..冏. 上面所谓的转化就是说,我本来安排人去排列,是无