hdu1081 dp 二维矩阵求最大连续子矩阵

O(n^3) 必然要讨论每种情况,每行必然要讨论0~0,0~1,0~2,...i~j(0<=i<=j<n)的情况,每行的每种情况都是一个确定的数值,则把n个【f(i,j)】可以看作求一个一维的最长连续子序列,这样讨论每种i,j分部情况,求出对应的一维最长子序列,这些子序列取max,即为题目所要求的最大连续子矩阵

其实我们可以再输入的时候,就把a[i][j]确定为第i行前j个数之和,即为0~j的分步,这样我们以后讨论序列start~end时,只要a[k][end]-a[k][start-1]即为star~endt的情况

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
using namespace std;
const int inf  = (1<<31)-1;
const int MAXN = 1e3+10;
int a[MAXN][MAXN];
int main()
{
    int n,tmp;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&tmp);
                a[i][j] = a[i][j-1]+tmp; //a[i][j为第k行前j个和
            }
        }
        int sum,mmax=-inf;
        for(int i=1;i<=n;i++){ //end后端
            for(int j=1;j<=i;j++){ //start前端
                sum = 0;
                for(int k=1;k<=n;k++){
                    sum = max(sum,0)+a[k][i]-a[k][j-1]; //一维的求法
                    mmax = max(mmax,sum);
                }
            }
        }
        cout<<mmax<<endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
}
View Code

起始我们讨论start,end的分布时,也可以这么想,我们可以讨论这些序列的长度l,必然为1~n,再讨论这些序列的起始节点j,完全可以确定这个序列的情况了,

start对应j,end对应j+l-1

posted @ 2016-04-11 00:46  iEdson  阅读(220)  评论(0编辑  收藏  举报