NCSTOJ 1134 蓝桥杯最大子阵

10 篇文章 2 订阅

NCSTOJ 1134 蓝桥杯最大子阵

Description

给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。 其中,A的子矩阵指在A中行和列均连续的一块。

Input

输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。(1 ≤ n, m ≤ 500)接下来n行,每行m个整数,表示矩阵A。

Output

输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。

Sample Input

3 3
-1 -4 3
3 4 -1
-5 -2 8

Sample Output

10

前缀和+动态规划

关键是如何把二维的子序和转化为一维

LeetCode 53.一维最大子序和解答

用一个数sum累加,如果sum>0说明累加当前的数是会变大或变小的(可能是最优解的一部分),如果sum<0那么就让sum等于当前数(因为不可能是最优解,要重新开始),因为累加不肯能比单独现在这个数大


方法:

这里二维转化成一维一个重点就是一维子序和范围可以理解成矩阵中的子矩阵

   1  2  3
1 -1 -1  3
2  3  4 -1
3 -5 -2  8

我选择第三列3,-1,8作为一个一维子序和时,可以得到结果10,这也是一个子矩阵,因为不管一维二维都是需要连续,二维连续就是子矩阵

范围怎么选定?答案是通过累加,我们不需要知道选的是哪里,只需要知道这一部分和就可以了,如这个例子的最优解是第二列加第三列,计算时只需要把第三列加到第二列,比较答案即可

把二维的子矩阵转化为一维的列的最大子序和,通过枚举所有的列可能性得到答案,列中的所有可能一维子序和帮你枚举了


代码实现:

数据从下标1开始存,初始化为0,这样不用判断范围,也不用担心会影响结果,范围num[n][m]

枚举所有的列,需要两个控制变量,一个是开始范围的i也就是从第几列开始 i ∈ [ 1 , m ] i \in [1,m] i[1,m],然后是从i开始的移动变量j也就是从i开始要几列 j ∈ [ i , m ] j\in[i,m] j[i,m],用一个数组dp保存第k行的数据,然后累加第j列,转化为一维子序和求解,更新最大值

#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
static const auto io_sync_off = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return nullptr;
}();

const int maxn = 505;
int num[maxn][maxn];
int dp[maxn];

int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            cin >> num[i][j];

    int ans = num[1][1]; // 初始化
    for (int i = 1; i <= m; ++i)
    {
        memset(dp, 0, sizeof(dp)); // 每次从不同行开始时要清零
        for (int j = i; j <= m; ++j)
        {
            for (int k = 1; k <= n; ++k)
                dp[k] += num[k][j]; // 累加第j列
            int mcur = dp[1], cur = 0; // 求一维最大子序和
            for (int k = 1; k <= n; ++k)
            {
                if (cur > 0)
                    cur += dp[k];
                else
                    cur = dp[k];
                mcur = max(mcur, cur);
            }
            ans = max(mcur, ans);
        }
    }
    cout << ans;
    return 0;
}

上述代码没有问题,但是求和的时候看着稍微有些累赘,并且要维护一个dp数组,仔细想想是可以通过前缀和得到某一列的值的,所以在输入数据时将其维护成前缀和数组,这样可以减少一个循环(按说时间因该没变化,但是更慢了wtf???)

要求某一块列的和,那么我们要对行累加(其实不是求列和,而是得到这一列到前面某一列范围内的每行和,就是上一个dp数组,越说越乱,手动模拟一下就好了)

#include <vector>
#include <iostream>
using namespace std;
static const auto io_sync_off = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return nullptr;
}();

const int maxn = 505;
int dp[maxn][maxn];

int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
        {
            cin >> dp[i][j];
            dp[i][j] += dp[i][j - 1]; // 求i行前缀和
        }

    int ans = dp[1][1];
    for (int i = 1; i <= m; ++i) // 枚举列
        for (int j = i; j <= m; ++j) // 要几列
        {
            int cursum = 0;
            for (int k = 1; k <= n; ++k) // 求j-i列之和组成的一维子序和最优解
            {
                if (cursum > 0)
                    cursum += dp[k][j] - dp[k][i - 1];
                else
                    cursum = dp[k][j] - dp[k][i - 1];
                ans = max(cursum, ans);
            }
        }
    cout << ans;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与国已互相成为双方最大的交易伙伴。国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占国外贸总值的15.4%。在过去20余年,东盟国家不断在全球多变的格局里面临挑战并寻机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电、整车、充电桩)、通信产业链(通信系统设备、终端设备、电元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值