[POJ1050]To the Max(最大子段和)

题目链接

http://poj.org/problem?id=1050

题意

求最大子矩阵和。

题解

  • 即求二维的最大子段和。二维数组sumRec[I][j]存储原始数组数据rec[0][j] to rec[I][j]。那么sum[k][j]-sum[I][j]即表示从I+1到k行的第j列这一列的元素和。然后再遍历j,就变成了求一维子段和的问题。共三重循环,时间复杂度O(n^3) 。
  • 求一维最大子段和方法:每遍历一个元素,先判断之前元素的累加和若为负,则直接舍去前面的所有累加元素,因为对和更大没有好处,和更新为0。累加和加上当前元素,并把当前累加和与最大累加和比较,更大则替换。

代码

import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int[][] sumRec=new int[n+1][n+1];
        for(int i=0;i<n;++i) {
            for(int j=0;j<n;++j) {
                sumRec[i][j]=in.nextInt();
                if(i!=0) {
                    sumRec[i][j]+=sumRec[i-1][j];
                }
            }
        }

        int maxSum=Integer.MIN_VALUE;
        for(int i=0;i<n;++i) {
            for(int k=i;k<n;++k) {
                int sum=0;
                for(int j=0;j<n;++j) {
                    if(sum<0) {
                        sum=0;
                    }
                    sum+=sumRec[k][j]-sumRec[i][j];
                    if(maxSum<sum) {
                        maxSum=sum;
                    }
                }
            }
        }
        System.out.println(maxSum);
    }
}

原文地址:https://www.cnblogs.com/coding-gaga/p/10992108.html

时间: 2024-10-29 00:29:13

[POJ1050]To the Max(最大子段和)的相关文章

POJ1050 To the Max - 贪心[最大子矩阵和]

POJ1050 To the Max 传送门 题意: 给定一个\(n*n\)的带权矩阵,求一个矩阵,使矩阵内权值之和最大,输出这个矩阵的权值和.$n\leq100 $ 思路: 可以利用前缀和优化,然后\(O(n^4)\)枚举矩阵的左上角和右下角,求出最大二维前缀和. 这样的枚举方案比较难以再次优化,我们考虑矩阵权值和的实质:等价于我们将矩阵每列的权值加起来,形成一个新数列,然后对这个数列求和,而最大的矩阵权值和,相当于在矩阵上下边界不变的情况下使新数列的和最大,即新数列的最大子段和.所以换种枚举

[POJ1050]To the Max (矩阵,最大连续子序列和)

数据弱,暴力过 题意 N^N的矩阵,求最大子矩阵和 思路 悬线?不需要.暴力+前缀和过 代码 //poj1050 //n^4暴力 #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #define N 105 #define INF 0x3fffffff using namespace std; int a[N][N]; int sum[N]; int ans; int

POJ1050 To the MAX 想法题

题意 给一个N*N的方阵,找出一个子矩阵,使子矩阵的和最大.(n<=100) 思路 一维的情况是经典的"最大连续和问题".我们考虑把二维的问题降到一维来.我们枚举最高的层和最低的层,把他们中间的值都加到一个tmp数组里,然后用tmp数组来做"最大连续和问题",不断更新ans.那么最后得出的ans一定是最大子矩阵. 代码 #include <cstdio> #include <algorithm> #include <cstring

[POJ1050]To the Max(最大子矩阵,DP)

题目链接:http://poj.org/problem?id=1050 发现这个题没有写过题解,现在补上吧,思路挺经典的. 思路就是枚举所有的连续的连续的行,比如1 2 3 4 12 23 34 45 123 234 345...然后把这些行对应列相加缩成一行,之后就是求最大子序列和了. 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃

hdoj 1003 Max Sum 【最大子段和】【贪心】

题意:... 策略:看着像贪心,感觉也是贪心. 很久之前做的,又做了一遍,好题. 代码: #include<stdio.h> #include<string.h> int s[100005]; int main() { int t, i, j, l, st, en, n, v = 1; scanf("%d", &t); while(t --){ scanf("%d", &n); for(i = 1; i <= n; i

HDU 1024 Max Sum Plus Plus【动态规划求最大M子段和详解 】

Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 29942    Accepted Submission(s): 10516 Problem Description Now I think you have got an AC in Ignatius.L's "Max Sum" problem

HDOJ-1003 Max Sum(最大连续子段 动态规划)

http://acm.hdu.edu.cn/showproblem.php?pid=1003 给出一个包含n个数字的序列{a1,a2,..,ai,..,an},-1000<=ai<=1000 求最大连续子段和及其起始位置和终止位置,很基础的动态规划(DP)问题,看完DP第一次做的DP题目 DP真的是一种很优美的算法,或者说思想,但是比较难理解,我对DP的理解还很浅薄 # include <stdio.h> # define INF 1000000000 int main() { i

hdu 1024 Max Sum Plus Plus (子段和最大问题)

Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17336    Accepted Submission(s): 5701 Problem Description Now I think you have got an AC in Ignatius.L's "Max Sum" problem

最大m子段和问题 Max Sum Plus Plus —— 动态规划

"最大m子段和" 问题 Max Sum Plus Plus 问题描述: 给定由n个整数(可能为负数)组成的序列a1,a2,a3--an,以及一个正整数m,要求确定此序列的m个不相交子段的总和达到最大.最大子段和问题是最大m字段和问题当m=1时的特殊情形. OJ题目源地址: http://acm.hdu.edu.cn/showproblem.php?pid=1024 Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    M