20241016每日一题洛谷P1115

普及- 洛谷 P1115 最大子段和

读题可知需要在一段一维数组中寻找一段唯一的区间,使区间内的数和最大,即寻找和最大区间

可以想到前缀和的算法

假设输入数组 a[n]

则前缀和数组 b[n]=b[n-1]+a[n]

那么从什么时候开始的一段区间才能使区间内的数和最大?

从前缀和数组逐步来判断这一条件

从 b[1] 开始,当 b[i] 即a的前 i 项前缀和 小于 a[i] 时,那么选取前 i 项 a 的前缀和还不如只从 a[i]开始选

这样就可以得出什么时候开始的一段区间才能使区间内的数和最大,即从 a 的第 i 项开始

将 b[i] 更新为 a[i],继续逐步判断,直到再次找到 b[j] 即a 从 a[i] ~ a[j] 的前缀和 小于 a[j] 时

我们可以说选到 a[j] 就足够了,此时就得到了一个在 a 的第 j 项前的一个区间使区间内的数和最大

将 b[j] 更新为 a[j] ,开启下一轮寻找和最大区间的操作

重复如上寻找和最大区间的操作,可以将每个和最大区间存储在一个数组中

这里我们采用一种节省空间的办法:在每次找到和最大区间后,对其进行判断,若是大于前一个和最大区间,则更新和最大区间

核心代码如下:

int a[200010], b[200010];
int main()
{
int n,max1;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if (i == 1) max1 = a[i];//初始化和最大区间为第一项
b[i] = max(a[i], b[i - 1] + a[i]);//逐步寻找到边界值,若b[i]<a[i]则更新b[i]为a[i],否则继续逐步计算前缀和
max1 = max(b[i], max1);//判断是否为最大的 和最大区间
}
printf("%d", max1);
return 0;
}

再次优化数组的代码:动态处理前缀和数组b和max1的值

int main()
{
int n,max1;
scanf("%d", &n);
int a, b = 0;//注意初始化b
for (int i = 1; i <= n; i++) {
scanf("%d", &a);
if (i == 1) max1 = a;
b = max(b + a, a);
max1 = max(a, b);
}
printf("%d", max1);
return 0;
}
posted @   才瓯  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示