当前位置: 首页 > news >正文

最大子数组和问题详解

模板题目链接:P1115 最大子段和 - 洛谷

1.Kadane 算法:        

        Kadane 算法是一种动态规划思想的算法,用于解决 最大子数组和 问题。该算法的时间复杂度为O(n)。

核心思想:

变量定义:        

        f[i]:表示为以当前元素结尾的最大子数组和。

        ans:表示全局最大子数组和。

状态转移方程:

        f[i] = max(x, f[i - 1] + x):如果当前元素加上以第 i - 1 个元素结尾的最大子数组和的和小于当前元素就从当前元素可以构造新的最大子数组,否则将当前元素加到之前的子数组中。

代码:

void solve()
{int n;cin >> n;vector<ll> f(n + 10, 0);ll ans = MIN;for (int i = 1; i <= n; ++i){ll x;cin >> x;f[i] = max(x, f[i - 1] + x);ans = max(ans, f[i]);}cout << ans << endl;
}

2.贪心解法:

核心思想:

变量定义:

        cnt:当前局部最大子数组和。

        ans:全局最大子数组和。

解法:

        在每次向当前子数组添加元素前先判断当前 cnt 是否大于 0,如果小于0就将 cnt 清空(cnt为负数代表如果将当前元素添加到子数组也和拉低后面的和),每次添加完元素后就将更新一次ans

代码:

void solve()
{int n;cin >> n;ll ans = MIN, cnt = 0;for (int i = 0; i < n; ++i){int x;cin >> x;if (cnt < 0)cnt = 0;cnt += x;ans = max(ans, cnt);}cout << ans << endl;
}

例题:

D - Flip to Gather

题目背景:

        给定一个长度为 n 的字符串 s,由 '0' 和 '1' 组成,目标是让 '1' 最多出现在一个区间内(可以没有),输出最小操作次数。

思路:

        我们希望通过一次选区间,把“1集中”做到最大,同时翻转尽量少。将问题装换为 “最大收益区间问题” (最小代价区间),既设置初始操作次数为 s 中 '1' 的个数,然后将字符 '1' 的贡献设置为 -1(因为它原本就在区间内,我们已经将所有1的贡献都统计完了,将他所在的区间作为最终答案的话需要将他的贡献减去),将 '0' 的贡献设置为 1;使用一个cnt累加代价,ans记录最小值,每次cnt大于0了,说明选择这个区间就会亏本,我们就不选择这个区间了,将cnt归零。

        注:这个题目与模板的区别为 题目需要找到最小代价区间,所有我们要在累加完之后再判断cnt是否将其归零。

时间复杂度:

        O(n)。

ac代码:

#include <bits/stdc++.h>#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)
using namespace std;typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<vector<int>> vvi;
typedef vector<int> vi;
typedef vector<bool> vb;const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;template <class T>
ostream &operator<<(ostream &os, const vector<T> &a) noexcept
{for (int i = 0; i < sz(a) - 10; i++)std::cout << a[i] << ' ';return os;
}template <class T>
istream &operator>>(istream &in, vector<T> &a) noexcept
{for (int i = 0; i < sz(a) - 10; i++)std::cin >> a[i];return in;
}/* 有乘就强转,前缀和开ll */void solve()
{int n;string s;cin >> n >> s;int sum = count(all(s), '1');ll ans = MAX, cnt = 0;for (int i = 0; i < n; ++i){if (s[i] == '1')--cnt;else++cnt;if (cnt > 0)cnt = 0;ans = min(ans, cnt);}cout << sum + ans << endl;
}int main()
{ioscc;int T;cin >> T;while (T--)solve();return 0;
}

相关文章:

  • nc 命令示例
  • Python训练第四十一天
  • LeRobot ACT——LeRobot对ALOHA ACT策略的封装:含源码解析与真机部署(效果比肩ACT原论文)
  • 上位机知识篇---直接无线数据通信
  • Broker、Proxy、Agent的区别
  • 哈尔滨工业大学提出ADSUNet—红外暗弱小目标邻帧检测新框架
  • Parametric Retrieval Augmented Generation
  • 每日八股文6.1
  • 6v6-导航收录:2025年网站自动引流终极方案 - 提升SEO排名新策略
  • win11回收站中出现:查看回收站中是否有以下项: WPS云盘回收站
  • springboot-响应接收与ioc容器控制反转、Di依赖注入
  • Cursor 中三个选项 Agent 、 Ask 和 Manual 含义
  • 2025年家用电梯品牌推荐榜单:聚焦品质与创新,探寻理想垂直出行方案
  • 【js逆向】信息公示平台搜索滑块逆向
  • C++: STL简介与string类核心技术解析及其模拟实现
  • 【芯片学习】555
  • 第二章支线四 ·响应圣坛:媒体查询与移动适配
  • Linux服务器 TensorFlow找不到GPU
  • 内网怎么映射外网ip? 内网的地址快速映射给外网访问用方法
  • 美业新动能:智能体如何赋能行业“维护”升级(3/6)
  • 优惠活动制作网站/如何建立一个自己的网站
  • 佳木斯做网站公司/网站设计公司
  • 网站建设论文3000字范文/营销策划公司排行榜
  • 网站后台系统设置/百度知道一下首页
  • 网站建设与栏目设置/杭州做百度推广的公司
  • 有服务器怎么做网站/百度网盘资源链接入口