POJ 1050 To the Max 矩阵最大和的子数组:动态规划

将原来的矩阵直接改造成dp矩阵
dp[i][j] 表示以以a[0][0]为左上角 a[i][j]为右下角的矩阵之和

所以一个O( n 4 n^{4} )的算法就比较容易写了

状态转移:
表示(不包括)左上角( ii , jj )右下角(i , j)的子矩阵和

ret = max(ret, a[i][j] + a[ii][jj] - a[i][jj] - a[ii][j]);
#include <iostream>
#include <stdio.h>
#include <limits.h>

using namespace std;

#define debug(x) cout<<#x<<": "<<x<<endl;

int a[101][101];
int N;
int ret = INT_MIN;

void disp(){
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
}
int main()
{

    while(cin>>N){
        for(int i=0;i<N*N;i++){
            scanf("%d",&a[i/N][i%N]);
        }
        ret = INT_MIN;
        for(int i=1;i<N;i++){
            a[i][0] = a[i-1][0] + a[i][0];
            a[0][i] = a[0][i-1] + a[0][i];
        }
        for(int i=1;i<N;i++){
            for(int j=1;j<N;j++){
                a[i][j] = a[i][j] + a[i-1][j] + a[i][j-1] - a[i-1][j-1];
                ret = max(ret,a[i][j]);
                //debug(i)
                //debug(j)
                for(int ii=0;ii<i;ii++){
                    ret = max(ret, a[i][j] -a[ii][j]);
                }
                for(int jj=0;j<j;jj++){
                    ret = max(ret, a[i][j] -a[i][jj]);
                }
                for(int ii=0;ii<=i;ii++){
                    for(int jj=0;jj<=j;jj++){
                        //debug(ii)
                        //debug(jj)
                        ret = max(ret, a[i][j] + a[ii][jj] - a[i][jj] - a[ii][j]);
                        //debug(a[i][j] + a[ii][jj] - a[i][jj] - a[ii][j])
                    }
                }
            }
        }
        //disp();
        cout<<ret<<endl;
    }
    return 0;
}

在这里插入图片描述

下面是 O ( n 3 ) O(n^{3}) 的解法

先求解每一个从i行至j行的第k列的和,从别存入dp[k]
在这里插入图片描述
对于dp数组,我们解决最大连续子序列的和即可


#include <iostream>
#include <stdio.h>
#include <limits.h>
#include <string.h>

using namespace std;

#define debug(x) cout<<#x<<": "<<x<<endl;

int a[101][101];
int N;
int ret = INT_MIN;
int dp[101];

void disp(){
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
}

int main(){
    while(cin>>N){
        ret = INT_MIN;
        //memset(a,0,sizeof(a));
        for(int i=0;i<N*N;i++){
            scanf("%d",&a[i/N][i%N]);
        }

        for(int i=0;i<N;i++){
            memset(dp,0,sizeof(dp));
            for(int j=i;j<N;j++){
                for( int k=0;k<N;k++ ){
                    dp[k] += a[ j ][k];
                }
                int temp = 0;
                for( int k=0;k<N;k++ ){
                    temp += dp[k];
                    ret = max(ret,temp);
                    if( temp < 0 ){
                        temp = 0;
                    }

                }
            }
        }
        cout<<ret<<endl;
    }
}

在这里插入图片描述

发布了286 篇原创文章 · 获赞 57 · 访问量 324万+

猜你喜欢

转载自blog.csdn.net/L1558198727/article/details/103206375