POJ1050-To the Max

描述:

  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. 

  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 the sum of the maximal sub-rectangle.

代码:

  这个题写了好几遍"( ̄▽ ̄)""",老想着有时间上的优化,然后不停的推翻。

  动态规划的依赖于问题的两个重要性质:最优子结构重叠子问题。如果想要在不同的子矩阵之间应用动态规划进行优化是有很大困难的。因为当你对一个子矩阵施以动规之后,在下一个包含这个子矩阵的更大的子矩阵想要利用这个结果,你得知道上一个子矩阵最优解的行列,以便组成一个新的最优解的矩阵。进一步思考产生了问题:无法证明大矩阵的最优解依赖于小矩阵的最优解。

  所以还是要挨个枚举所有的子阵。这里可以只枚举行,然后以列求和,转化为最大连续字串和的问题。

  比如对于子段:9 2 -16 2,temp[i]表示以ai结尾的子段中的最大子段和。在已知temp[i]的情况下,求temp [i+1]的方法是:

  如果temp[i]>0,temp [i+1]= temp[i]+ai(继续在前一个子段上加上ai),否则temp[i+1]=ai(不加上前面的子段,越加越小不如抛弃),然后记录temp产生的最大值即可。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include <math.h>
using namespace std;
#define N 105
#define MIN -999999

int main(){
    int matrix[N][N],n,b[N],temp,max_temp,max_sum;
    cin>>n;
    for( int i=1;i<=n;i++ ){
        for( int j=1;j<=n;j++ ){
            cin>>matrix[i][j];
        }
    }
    max_sum=MIN;
    for( int i=1;i<=n;i++ ){//开始行
        memset(b,0,sizeof(b));
        for( int j=i;j<=n;j++ ){//结束行
            for( int k=1;k<=n;k++ ){//
                b[k]+=matrix[j][k];//将行为i-j的子阵的每列单独求和,转化为1维的最大字串和问题
            }
            //最大字串和
            temp=max_temp=0;
            for( int k=1;k<=n;k++ ){
                temp=(temp>0)?temp+b[k]:b[k];
                max_temp=(max_temp>temp)?max_temp:temp;
            }
            max_sum=max(max_sum,max_temp);
        }
    }
    printf("%d\n",max_sum);
    system("pause");
    return 0;
}

 

posted @ 2015-08-30 10:45  Lucio.Yang  阅读(208)  评论(0编辑  收藏  举报