Poj 1050 动态规划

本文介绍了一种求解二维矩阵中元素和最大子矩阵的方法。通过将问题转化为多个一维数组的最大子串和问题来简化求解过程,并提供了一个有效的实现方案。文章还讨论了如何优化算法以减少运行时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:给一个方矩阵,求解元素和最大的子矩阵。最终要求输出最大和结果。

题目分析:一位数组的最大和通过动态规划是很好解决的,利用如下递推公式即可:

dp[i]=max{dp[i1]+A[i],A[i]}

然而这是一个二维的问题。
一开始,按照动态规划的思想,我期望把问题归结为一个最优子问题,但是失败了。后来把问题规划为一维数组解决,是很好的。具体做法是把矩阵的连续行加起来变成一个一维数组,求解最大子串和。以4*4的矩阵为例,连续行相加的可能有4+3+2+1种,分别是一行、两行、三行、四行的情况。我们能够得到10个一维数组,对其进行最大子串和的求取,最终选取最大的结果即可。

思路清晰了,但是代码还是很多次没过,原因就是超时。
之前的思路是这样的:循环i为一行、两行、三行、四行的情况。内层循环j为结束行。定义一个数组B存储结果,对于每一行的k列,k再进行一个循环。然后第k个元素需要从j-i行加到j行,这又需要一层循环。一共是四层循环,这就肯定超时了。

后来改进了一下,变成了三层循环。重新定义了i和j,定义i为起始行,j为结束行。这样i从1到N,j从i到N,就可以遍历所有的情况。在ij内层定义一个k循环,计算B[k]+=A[j][k]。这样随着j增加,B[k]会变成多行之和,然后改变i的时候初始化一下B即可。这样就变成三层循环了,顺利通过。可见这个程序的设计还是需要多加考虑的。

#include <iostream>
#include <cstring>

using namespace std;

int N;
int A[510][510];
int B[510];
int dp[510];
int ans = -9999;
int main()
{
    cin >> N;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            cin >> A[i][j];
        }
    }
    for (int i = 0; i < N; i++)
    {
        memset(B,0, sizeof(B));
        for (int j = i; j < N; j++)
        {
            for (int k = 0; k < N; k++)
            {
                B[k] += A[j][k];
                if (!k)
                    dp[0] = B[0];
                else
                    dp[k] = dp[k - 1]>0 ? dp[k - 1] + B[k] : B[k];
                ans = dp[k] > ans ? dp[k] : ans;
            }
        }
    }
    cout << ans << endl;
    //system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值