题目地址:http://poj.org/problem?id=1050

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 of all the elements in that rectangle.
In this problem the sub-rectangle with the largest sum is referred to as the maximal sub-rectangle.
As an example, the maximal sub-rectangle of the array:

0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
is in the lower left corner:

9 2
-4 1
-1 8
and has a sum of 15.

Input

The input consists of an N * N array of integers. The input begins with a single positive integer N on a line by itself, indicating the size of the square two-dimensional array. This is followed by N^2 integers separated by whitespace
(spaces and newlines). These are the N^2 integers of the array, presented in row-major order. That is, all numbers in the first row, left to right, then all numbers in the second row, left to right, etc. N may be as large as 100. The numbers in the array will
be in the range [-127,127].

Output

Output the sum of the maximal sub-rectangle.

Sample Input

4
0 -2 -7 0 9 2 -6 2
-4 1 -4 1 -1 8 0 -2

Sample Output

15

时间复杂度为O(N^2*M^2)

#include <stdio.h>
#include <limits.h> //PS[i][j]等于以(1, 1), (1, j), (i, 1), (i, j)为顶点的矩形区域的元素之和
void Preproccess(int matrix[101][101], int PS[101][101], int N){
int i, j;
for (i=0; i<=N; ++i){
PS[0][i] = 0;
PS[i][0] = 0;
}
for (i=1; i<=N; ++i){
for (j=1; j<=N; ++j){
PS[i][j] = PS[i-1][j] + PS[i][j-1] - PS[i-1][j-1] + matrix[i][j];
}
}
} int main(void){
int N;
int matrix[101][101];
int PS[101][101];
int i, j;
int i_min, i_max;
int j_min, j_max;
int max, tmp; while (scanf ("%d", &N) != EOF){
for (i=1; i<=N; ++i)
for (j=1; j<=N; ++j)
scanf ("%d", &matrix[i][j]);
Preproccess(matrix, PS, N);
max = INT_MIN;
/*以(i_min, j_min), (i_max, j_min), (i_min, j_max), (i_max, j_max)为顶点的矩形区域的元素之和,
等于PS[i_max][j_max] - PS[i_min-1][j_max] - PS[i_max][j_min-1] + PS[i_min-1][j_min-1]
*/
for (i_min=1; i_min<=N; ++i_min){
for (i_max=i_min; i_max<=N; ++i_max){
for (j_min=1; j_min<=N; ++j_min){
for (j_max=j_min; j_max<=N; ++j_max){
tmp = PS[i_max][j_max] - PS[i_min-1][j_max] - PS[i_max][j_min-1] + PS[i_min-1][j_min-1];
if (tmp > max)
max = tmp;
}
}
}
}
printf ("%d\n", max);
} return 0;
}

时间复杂度为O(N*M*min(N, M))

#include <stdio.h>
#include <limits.h> //PS[i][j]等于以(1, 1), (1, j), (i, 1), (i, j)为顶点的矩形区域的元素之和
void Preproccess(int matrix[101][101], int PS[101][101], int N){
int i, j;
for (i=0; i<=N; ++i){
PS[0][i] = 0;
PS[i][0] = 0;
}
for (i=1; i<=N; ++i){
for (j=1; j<=N; ++j){
PS[i][j] = PS[i-1][j] + PS[i][j-1] - PS[i-1][j-1] + matrix[i][j];
}
}
} //BC(PS, a, c, i)表示在第a行和第c行之间的第i列的所有元素的和,可以通过“部分和”PS[i][j]在O(1)时间内计算出来。
int BC(int PS[101][101], int a, int c, int i){
return PS[c][i] - PS[a-1][i] - PS[c][i-1] + PS[a-1][i-1];
} int MaxSum (int matrix[101][101], int PS[101][101], int N){
int max = INT_MIN;
int a, c, i;
int Start, All;
for (a=1; a<=N; ++a){
for (c=a; c<=N; ++c){
Start = BC(PS, a, c, N);
All = BC(PS, a, c, N);
for (i=N-1; i>=1; --i){
if (Start < 0)
Start = 0;
Start += BC(PS, a, c, i);
if (Start > All)
All = Start;
}
if (All > max)
max = All;
}
}
return max;
} int main(void){
int N;
int matrix[101][101];
int PS[101][101];
int i, j; while (scanf ("%d", &N) != EOF){
for (i=1; i<=N; ++i)
for (j=1; j<=N; ++j)
scanf ("%d", &matrix[i][j]);
Preproccess(matrix, PS, N);
printf ("%d\n", MaxSum (matrix, PS, N));
} return 0;
}

HDOJ上相似的题目:http://acm.hdu.edu.cn/showproblem.php?pid=1559

九度OJ上相似的题目:http://ac.jobdu.com/problem.php?pid=1492

参考资料:编程之美

POJ 1050 To the Max -- 动态规划的更多相关文章

  1. [ACM_动态规划] POJ 1050 To the Max ( 动态规划 二维 最大连续和 最大子矩阵)

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

  2. POJ 1050 To the Max 最大子矩阵和(二维的最大字段和)

    传送门: http://poj.org/problem?id=1050 To the Max Time Limit: 1000MS   Memory Limit: 10000K Total Submi ...

  3. poj 1050 To the Max(最大子矩阵之和)

    http://poj.org/problem?id=1050 我们已经知道求最大子段和的dp算法 参考here  也可参考编程之美有关最大子矩阵和部分. 然后将这个扩大到二维就是这道题.顺便说一下,有 ...

  4. POJ 1050 To the Max 暴力,基础知识 难度:0

    http://poj.org/problem?id=1050 设sum[i][j]为从(1,1)到(i,j)的矩形中所有数字之和 首先处理出sum[i][j],此时左上角为(x1,y1),右下角为(x ...

  5. poj 1050 To the Max (简单dp)

    题目链接:http://poj.org/problem?id=1050 #include<cstdio> #include<cstring> #include<iostr ...

  6. poj - 1050 - To the Max(dp)

    题意:一个N * N的矩阵,求子矩阵的最大和(N <= 100, -127 <= 矩阵元素 <= 127). 题目链接:http://poj.org/problem?id=1050 ...

  7. poj 1050 To the Max(线性dp)

    题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...

  8. poj 1050 To the Max(最大子矩阵之和,基础DP题)

    To the Max Time Limit: 1000MSMemory Limit: 10000K Total Submissions: 38573Accepted: 20350 Descriptio ...

  9. poj 1050 To the Max

    To the Max Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 45906   Accepted: 24276 Desc ...

随机推荐

  1. Oracle用户及角色的权限管理[Oracle基础]

    1.查看全部用户:   select * from dba_users;   select * from all_users;   select * from user_users; 2.查看用户或角 ...

  2. 03---JavaScript基础整理

    一.概述:           Netscape开发的一种基于对象和事件驱动的脚本语言.                  被设计用来想HTML页面添加交互行为.           无需编译,可由浏 ...

  3. Python 魔术方法指南

    入门 构造和初始化 构造定制类 用于比较的魔术方法 用于数值处理的魔术方法 表现你的类 控制属性访问 创建定制序列 反射 可以调用的对象 会话管理器 创建描述器对象 持久化对象 总结 附录 介绍 此教 ...

  4. 内网架设SVN服务器相关设置

    环境说明:        外网IP为静态IP,工作室内有多台电脑,公用一台路由器.想要在某台电脑上架设SVN服务器,方便团队开. 解决方案: 一.准备工作1.获取 Subversion 服务器程序到官 ...

  5. 老蜗牛写采集:一个漂亮的客户端-几个C#平台下的Winform 皮肤控件

    搞采集多年,避免不了搞个简单的UI来曹州,所谓人靠衣装马靠鞍,一套漂亮的皮肤会给你的程序带来高大上的感觉.有时候老板也是看心情的,好的东西总归可以避免点缺点.今天给大家介绍几个曾经研究过的WinFor ...

  6. 聊聊Iconfont

    一.前言 说起Iconfont,对大多数人来说可能不是什么新的技术了,现在好多大网站已经开始使用Iconfont.博主今天主要是简单说一下它的使用方法,聊聊使用它时可能遇到哪些坑,不熟悉的同学可以简要 ...

  7. View绘制详解(三),扒一扒View的测量过程

    所有东西都是难者不会,会者不难,Android开发中有很多小伙伴觉得自定义View和事件分发或者Binder机制等是难点,其实不然,如果静下心来花点时间把这几个技术点都研究一遍,你会发现其实这些东西都 ...

  8. 将HTML表格导出到EXCEL,兼容Firefox,支持中文

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. [转]Creating Unit Tests for ASP.NET MVC Applications (C#)

    本文转自:http://www.asp.net/mvc/tutorials/older-versions/unit-testing/creating-unit-tests-for-asp-net-mv ...

  10. LintCode 55 比较字符串

    比较两个字符串A和B,确定A中是否包含B中所有的字符.字符串A和B中的字符都是 大写字母 注意事项 在 A 中出现的 B 字符串里的字符不需要连续或者有序.   样例 给出 A = "ABC ...