首页 > 其他分享 >题解 P1115 最大子段和

题解 P1115 最大子段和

时间:2024-07-22 10:17:59浏览次数:10  
标签:P1115 子段 int 题解 mi cin ans tie cout

容易想到朴素做法:

for (int l = 1; i <= n; ++i) {
    for (int r = 1; j <= n; ++j) {
        int v = s[r] - s[l - 1];
        ans = max(ans, v);
    }
}

但是显然 \(\mathrm{\color{#052242}TLE}\)

再回头看代码:想要 v 最大,只需要 \(\large{S_{l - 1}}\) 最小即可。

于是我们可以 \(O(n)\) 的动态更新 \(S_0 \sim S_{i-1}\) 最小值 \(\min_{1 \le i \le N}{S_i}\)

int m[N];
for (int i = 1; i <= n; ++i) {
    m[i] = min(m[i - 1], s[i]);
}

然后随 \(M_i\) 的更新,更新答案 \(ans = \max(S_i-M_{i-1})\) 即可。

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 10;

int a[N], m[N], s[N];
int n;

int main()
{
    ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
    
    
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        cin >> a[i];
        s[i] = s[i - 1] + a[i];
        m[i] = min(m[i - 1], s[i]);
    }
    int ans = -2e4;
    for(int i = 1; i <= n; ++i)
    {
        ans = max(ans, s[i] - m[i - 1]);
    }
    cout << ans;
	return 0;
}//ACed

但是显然这份代码可以优化。

优化

1.

我们发现求完前缀和后,\(A_i\) 就没用了。

于是可以优化掉 \(A_i \to t\)。

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 10;

int m[N], s[N];
int n;

int main()
{
    ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
    
    
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        int t; cin >> t;
        s[i] = s[i - 1] + t;
        m[i] = min(m[i - 1], s[i]);
    }
    int ans = -2e4;
    for(int i = 1; i <= n; ++i)
    {
        ans = max(ans, s[i] - m[i - 1]);
    }
    cout << ans;
	return 0;
}//ACed

2.

两个循环都是 \(\mathrm{for\space\space i=1\sim N}\)。可以合并减小常数

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 10;

int m[N], s[N], ans = -2e4;
int n;

int main()
{
    ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
    
    
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        int t; cin >> t;
        s[i] = s[i - 1] + t;
        m[i] = min(m[i - 1], s[i]);
        ans = max(ans, s[i] - m[i - 1]);
    }
    cout << ans;
	return 0;
}//ACed

3.

发现只需要用到 \(M_{i - 1}\) 于是 \(M_{i - 1} \to mi\) 且每次求完答案后更新 \(mi\) 即可。

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 10;

int mi, s[N], ans = -2e4;
int n;

int main()
{
    ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
    
    
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        int t; cin >> t;
        s[i] = s[i - 1] + t;
        ans = max(ans, s[i] - mi);
        mi = min(mi, s[i]);
    }
    cout << ans;
	return 0;
}

4.

同理,只需要用到 \(S_i\),优化掉即可

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 10;

int mi, s, ans = -2e4;
int n;

int main()
{
    ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
    
    cin >> n;
    for(int i = 1; i <= n; ++i) {
        int t; cin >> t;
        s += t;
        ans = max(ans, s - mi);
        mi = min(mi, s);
    }
    cout << ans;
	return 0;
}

标签:P1115,子段,int,题解,mi,cin,ans,tie,cout
From: https://www.cnblogs.com/lstylus/p/18315559

相关文章

  • 题解:P7482 不条理狂诗曲
    题解:P7482不条理狂诗曲本题解借鉴blossom_j大佬思路,但这位大佬的题解似乎没放正确代码。题意对于每一个\(a\)的子区间\(a_{l\dotsr}\),求选择若干个不连续的数的和的最大值,对答案取模\(10^{9}+7\)。思路主要算法:分治。计算跨过中点\(mid\)的区间的\(f\)之和。首......
  • P3041 [USACO12JAN] Video Game G 题解 AC自动机
    本题是一道AC自动机上的dp。首先不难想到状态定义f(i,j)表示仅考虑前i 个位置,第i 个字符是j 的分数,但无法转移,所以考虑将j这一维转化为表示AC自动机上的点。再定义val(i)表示以i 结尾的所有技能种数,则转移方程为f(i,j)=max(f(i,j),f(i-1,father(j)+val(j......
  • Loj P10064 黑暗城堡 题解 最短路径树记数
    这道题是一道最短路径树问题。首先,什么是最短路径树呢?定义一个图的最短路径树表示一个图上的生成树,且根节点到图上任一点的距离等于原图上两者之间的距离。而不难发现,题目其实是在求图上最短路径树记数。首先,建出最短路径树。枚举每条边,判断边两个端点到根的距离之差是否为......
  • 【题解】P4648 [IOI2007] pairs 动物对数
    Problem给定模板\(B(1\leB\le3)\),代表\(B\)维空间。其中有\(n\)个点,给出坐标与坐标上限\(M\),求\(n\)个点中曼哈顿距离\(\leD\)的对数。Solve\(B=1\)考虑将问题化简成:求\(\sum\limits_{i=1}^n\sum\limits_{j=1}^{i-1}[dis(i,j)\leqD]\)。其中\(dis(i,j)\)......
  • 圆方树学习笔记 & 最短路 题解
    前言圆方树学习笔记,从一道例题讲起。题目链接:Hydro&bzoj。题意简述仙人掌上求两点距离。题目分析为了把仙人掌的性质发挥出来,考虑将其变成一棵树。圆方树就是这样转换的工具。先讲讲圆方树的概念:原图上的点为圆点,每个点双对应一个方点,树边都是方点连向点双内的圆点。具......
  • 跑步爱天天 题解
    题意简述一棵以\(1\)为根的树,儿子间有先后顺序。初始每个结点上有一个警卫,警卫按照深度优先遍历其子树,儿子间的先后顺序体现在这里,回到起始点后开始新一轮的遍历。yzh想要从\(S\)走到\(1\),请问她会在路上遇到多少警卫(\(S\)点的也算)。题目分析法\(1\)先来讲一讲我考场......
  • 题解:Codeforces Round 960 (Div. 2) D
    D.GridPuzzletimelimitpertest:2secondsmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputYouaregivenanarray\(a\)ofsize\(n\).Thereisan\(n\timesn\)grid.Inthe\(i\)-throw,thefirst\(a_i\)......
  • 【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的生日派对座位安排(200分) - 三
    ......
  • 题解:Codeforces Round 960 (Div. 2) C
    C.MadMADSumtimelimitpertest:2secondsmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputWedefinethe\(\operatorname{MAD}\)(MaximumAppearingDuplicate)inanarrayasthelargestnumberthatappearsatleast......
  • NOI2024 集合 题解
    给个链接:集合。很神秘的题目。基本上看到之后就可以想到哈希。首先想到一个比较神秘的暴力。就是对于每个询问,扫一遍所有\(a\)中的数出现的位置,把它弄成一个哈希值(具体怎么弄随意)存到set里,然后看看是不是和\(b\)中的数出现的位置这样操作后的集合完全相等。事实上就是判断......