惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
IT之家
IT之家
H
Heimdal Security Blog
Jina AI
Jina AI
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
C
Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Hacker News
The Hacker News
The Cloudflare Blog
Hugging Face - Blog
Hugging Face - Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
S
Securelist
P
Privacy International News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
博客园 - 叶小钗
J
Java Code Geeks
V
V2EX
博客园 - Franky
Spread Privacy
Spread Privacy
K
Kaspersky official blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Simon Willison's Weblog
Simon Willison's Weblog
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
C
Cybersecurity and Infrastructure Security Agency CISA
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
NISL@THU
NISL@THU
罗磊的独立博客
W
WeLiveSecurity
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园_首页
V
Visual Studio Blog

博客园 - 糖豆爸爸

【树上DP前导知识汇总】 快速幂、龟速乘总结 反向建图+拓扑排序 卡特兰数专题(Catalan) AcWing 431. 守望者的逃离 AcWing 414. 数字游戏 AcWing 468. 魔法阵 AcWing 463. 求和 洛谷 P1632 点的移动 P1056 NOIP2008 普及组 排座椅 洛谷 P1889 士兵站队 洛谷 P1862 输油管道问题 CF444C DZY Loves Colors P2253 好一个一中腰鼓! SCOI2010 P2572 序列操作 P4344 SHOI2015 脑洞治疗仪 T125847 【模板】动态开点线段树 P3373 【模板】线段树 2 Physical Education Lessons
AcWing 126. 最大的和
糖豆爸爸 · 2023-10-06 · via 博客园 - 糖豆爸爸

\(AcWing\) \(126\). 最大的和

关键字

最大子段和,有一维和二维两种情况
一维:\(O(N)\)
二维:\(O(n^3)\)

一、题目描述

给定一个包含整数的二维矩阵,子矩形是位于整个阵列内的任何大小为 \(1×1\) 或更大的连续子阵列。

矩形的总和是该矩形中所有元素的总和。

在这个问题中,具有最大和的子矩形被称为最大子矩形。

例如,下列数组:

0 -2 -7 0 
9 2 -6 2 
-4 1 -4 1 
-1 8 0 -2 

其最大子矩形为:

9 2 
-4 1 
-1 8 

它拥有最大和 \(15\)

输入格式
输入中将包含一个 \(N×N\) 的整数数组。

第一行只输入一个整数 \(N\),表示方形二维数组的大小。

从第二行开始,输入由空格和换行符隔开的 \(N^2\) 个整数,它们即为二维数组中的 \(N^2\) 个元素,输入顺序从二维数组的第一行开始向下逐行输入,同一行数据从左向右逐个输入。

数组中的数字会保持在 \([−127,127]\) 的范围内。

输出格式
输出一个整数,代表最大子矩形的总和。

数据范围
\(1≤N≤100\)

输入样例

4
0 -2 -7 0 
9  2 -6 2
-4 1 -4 1 
-1 8 0 -2

输出样例

15

二、一维情况

测试用例

7
5 -2 -4 8 -1 5 4

输出

16
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 110;
int a[N], s[N];
int f[N];
/*
7
5 -2 -4 8 -1 5 4

输出:
16
*/
int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        s[i] = s[i - 1] + a[i]; // 累加出前缀和
    }

    int res = -INF;

    for (int i = 1; i <= n; i++) {
        f[i] = max(f[i - 1], 0) + a[i];
        res = max(res, f[i]);
    }
    cout << res << endl;

    return 0;
}

三、二维情况

左上角和右下角两个点可以确定一个矩形。枚举这两个点要用\(4\)\(for\)循环 如果 用二维前缀和优化,那么这个做法的复杂度的就是\(O(n^4)\)

其实这个方案可以优化,那就是 不枚举点

所以我们可以 利用前缀和数组表示出每个色块表示的值,然后做类似找一维数组最大连续和的操作。这样来 枚举出最优矩形

枚举边界要用\(3\)\(for\),复杂度为 \(O(n^3)\)

\(Code\)

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 110;
int g[N][N];

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) {
            cin >> g[i][j];
            // 累加出并记录同一列的前缀和
            g[i][j] += g[i - 1][j];
        }

    int res = -INF;

    // 枚举边界1,2
    for (int i = 1; i <= n; i++)       // 起始行
        for (int j = i; j <= n; j++) { // 终止行
            // 枚举边界p
            int last = 0;
            for (int k = 1; k <= n; k++) {
                last = max(last, 0) + g[j][k] - g[i - 1][k];
                res = max(res, last);
            }
        }

    cout << res << endl;
    return 0;
}