动态规划经典题目——最大子矩阵和

一、题目

题目描述:现给出一个N*N矩阵,要求求出拥有最大和的子矩阵的和。例子如下图所示:

它的最大子矩阵的和为15;

二、解题思路

     此题的解法与动态规划经典题目——最大连续子序列之和题目思想一样,只不过本题是二维空间上的拓展。N*N矩阵用二维数组a[N][N]表示。我们解决新问题的方法是借鉴我们以前解决过的类似问题的方法和思路,当然本题也不例外,通过思考可以发现,这道题目与动态规划经典题目——最大连续子序列之和非常相似,只不过动态规划经典题目——最大连续子序列之和它是一维的问题,而本题目是二维问题,我们是否能把二维问题转化为一维问题吗?通过认真的考虑是可以的,我们可以把每列的元素进行合并为一个元素(可以定义二维数组sum[][],其中sum[i]表示前i行每列数字相加的和,所以sum[j][] - sum[i][]为一维向量),这样运用动态规划经典题目——最大连续子序列之和的思想了。

①定义状态

根据上面的分析,我们定义二维数组dp[i][j]表示第i行到第j行中的最大子矩阵和。所以我们要求的最大子矩阵和为max(dp[i][j])其中0≤i≤j≤N;

②定义状态转移方程

大家知道动态规划满足无后向性,即:每个阶段的决策仅受之前决策的影响,但是不影响之后各阶段的决策。所以我们可以从后往前推出状态转移方程,具体定义可参考动态规划经典题目——最大连续子序列之和中的状态转移方程。

三、代码编写

#include <stdio.h>
#include <stdlib.h>

#define N 4
#define max(a,b) ((a > b)?a:b)

int main()
{
    //定义矩阵
    int a[N][N] = { {0,-2,-7,0},
                    {9,2,-6,2},
                    {-4,1,-4,1},
                    {-1,8,0,-2}};
    //定义二维数组sum[][],其中sum[i]表示前i行每列数字相加的和,
    //所以sum[j][] - sum[i][]为一维向量
    int sum[N+1][N] = {0};
    int temp = 0 ;
    //保存最大子矩阵和
    int maxResult = 0;
    //给sum数组赋值
    int i,j,k;
    for(i=1 ; i < N+1 ; i++){
        for(j=0 ; j < N ; j++){
            sum[i][j] = sum[i-1][j] + a[i-1][j];
        }
    }
    //核心算法
    for(i=0 ; i < N ; i++){
        for(j=i+1 ; j < N+1 ; j++){
            temp = 0 ;
            for(k=0 ; k < N ; k++){
                temp += (sum[j][k] - sum[i][k]);
                if(temp > maxResult){
                    maxResult = temp;
                }
                if(temp < 0){
                    temp = 0;
                }
            }
        }
    }
    printf("最大子矩阵和为:%d",maxResult);
    return 0;
}

 四、运行结果

 

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值