To the Max
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 39913   Accepted: 21099

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

Source

这是hdu 1003的拓展,知道了在一维数组中如何求最大连续子段和,那么这题就是扩展到二维数组中,让我们求出子矩阵最大的和,我们可以这样考虑,我们把同行不同列(或者同列不同行)的加起来,比如i行,j行,i,j两行之间的数字组成了一个矩阵,我们把i行到j行之间同列的数组元素加起来按照列号组成一个一维数组,这样我们只需要利用最大子段和的知识找出这个数组的最大连续和,这个和就是我们要求的那个子矩阵最大和! 可以说, i和j行定义了子矩阵高度,一维数组最大子段和连续的长度定义了子矩阵的宽度,OK,代码。
 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int temp[],n;
int cal() //
{
int Max = temp[];
int sum = temp[];
for(int i = ;i<n;i++)
{
if(sum+temp[i]<temp[i])
sum = temp[i];
else
sum+=temp[i];
if(Max<sum)
Max = sum;
}
return Max;
} int main()
{
while(scanf("%d",&n)!=EOF)
{
int a[][];
for(int i = ;i<n;i++)
for(int j = ;j<n;j++)
scanf("%d",&a[i][j]);
int Max = ;
for(int i = ;i< n;i++) //i是起始行
{
for(int j =i ;j<n;j++) //j是终止行
{
memset(temp,,sizeof(temp));
for(int m = ;m<n;m++) //固定列,注意是行在变
{
for(int k =i ;k<=j;k++) //累加i起始行,j终止行中间的同列的数据
temp[m]+=a[k][m];
}
int MaxTemp = cal();
if(MaxTemp>Max)
Max = MaxTemp;
} }
printf("%d\n",Max);
}
return ;
}

事实证明我蠢了,后来看到nyoj这题的最优程序解答,在处理第i行到j行同列相加上面处理的很好,利用输入时候进行累加,然后做减法,直接减掉了一层循环

nyoj 的版本


 #include<iostream>
#include<cstring>
using namespace std;
#define N 110
int a[N][N];
int b[N];
int main()
{
int n,r,c;
cin>>n;
while(n--)
{
cin>>r>>c;
for(int i=;i<=r;++i)
for(int j=;j<=c;++j)
{
cin>>a[i][j];
a[i][j]+=a[i-][j];
}
int max=a[][];
for(int i=;i<=r-;++i)
for(int j=i+;j<=r;++j)
{
memset(b,,sizeof(b));
for(int k=;k<=c;++k)
{
if(b[k-]>=)
b[k]=b[k-]+a[j][k]-a[i][k];
else
b[k]=a[j][k]-a[i][k];
if(max<b[k])
max=b[k];
}
}
cout<<max<<endl;
}
}

还有一种没有用这种求和的方法,但是是先求第一行最大子段和,再求第一行跟第二行合起来的最大子段和,,再求第一到第三合起来的最大子段和,以此类推,直到求出整个矩阵的合起来的最大子段和,最后就是我们需要的解 。

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int temp[],n;
int cal() //最大子段和
{
int Max = temp[];
int sum = temp[];
for(int i = ;i<n;i++)
{
if(sum+temp[i]<temp[i])
sum = temp[i];
else
sum+=temp[i];
if(Max<sum)
Max = sum;
}
return Max;
} int main()
{
while(scanf("%d",&n)!=EOF)
{
int a[][];
for(int i = ;i<n;i++)
for(int j = ;j<n;j++)
scanf("%d",&a[i][j]);
int Max = ;
for(int i = ;i< n;i++)
{
memset(temp,,sizeof(temp));
for(int j =i ;j<n;j++)
{
for(int k = ;k<n;k++)
temp[k]+=a[j][k];
int t = cal();
if(t>Max)
Max =t;
} }
printf("%d\n",Max);
}
return ;
}

poj1050(nyoj104 zoj1074)dp问题的更多相关文章

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

    题目链接:http://poj.org/problem?id=1050 发现这个题没有写过题解,现在补上吧,思路挺经典的. 思路就是枚举所有的连续的连续的行,比如1 2 3 4 12 23 34 45 ...

  2. ZOJ1074 (最大和子矩阵 DP)

    F - 最大子矩阵和 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u   Descri ...

  3. poj1050 dp动态规划

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

  4. POJ1050【DP】

    题意: 求一个最大子矩阵和. 思路: 枚举行区间,然后求一个最大子序列和. 贴一发挫code- #include <iostream> #include <cstdio> #i ...

  5. POJ1050(dp)

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

  6. (线性dp 最大子段和 最大子矩阵和)POJ1050 To the Max

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

  7. poj1050 To the Max(降维dp)

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

  8. DP总结 ——QPH

    常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一 ...

  9. POJ1050:To the max

    poj1050:http://poj.org/problem?id=1050 * maximum-subarray 问题的升级版本~ 本题同样是采用DP思想来做,同时有个小技巧处理:就是把二维数组看做 ...

随机推荐

  1. nc命令总结

    1.远程拷贝文件从server1拷贝文件到server2上.需要先在server2上,用nc激活监听,server2上运行: 引用 [root@hatest2 tmp]# nc -l 1234 > ...

  2. CSS发光边框文本框效果

    7,166 次阅读 ‹ NSH Blog 网页设计 CSS发光边框文本框效果 或许你看过Safari浏览器下,任何输入框都会有一个发光的蓝色边框,这不单纯只是蓝色边框而已,其实包含了许多CSS3技巧知 ...

  3. UESTC_秋实大哥与快餐店 2015 UESTC Training for Data Structures<Problem C>

    C - 秋实大哥与快餐店 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Sub ...

  4. UESTC_贪吃蛇 CDOJ 709

    相信大家都玩过贪吃蛇游戏吧. 在n×m的迷宫中,有着一条长度不超过9的贪吃蛇,它已经将所有的食物吃光了,现在的目标是移动到出口. 它走的时候不能碰到自己的身体,也不能碰到墙壁.(如果贪吃蛇的长度> ...

  5. Combination Sum II 解答

    Question Given a collection of candidate numbers (C) and a target number (T), find all unique combin ...

  6. Rotate Array 解答

    Question Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, t ...

  7. Android ScrollView用法

    Android ScrollView用法 今天试着使用了一下Android的滚轮,以下是一个小小的测试,读取测试文件,主要是使用scrollTo函数和getScrollY(),程序点击BUTTON按钮 ...

  8. Struts2(二)——配置文件struts2.xml的编写

    接上一篇博客,这篇博客讲述一下2——9小标题的内容,这些问题都可以在struts2配置文件中设置(当然有的也可以在Struts.properties属性文件,web.xml中进行设置),而且常规开发中 ...

  9. Young Table(暴力,交换位置)

     Young Table Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submi ...

  10. 修改linux共享内存大小

    这是实际linux系统显示的实际数据: beijibing@bjb-desktop:/proc/sys/kernel$ cat shmmax  33554432 beijibing@bjb-deskt ...