洛谷P1614 爱与愁的心痛(滑动窗口解法)
1.洛谷P5707 【深基2.例12】上学迟到2.洛谷P5710 【深基3.例2】数的性质3.洛谷P1914 小书童——凯撒密码4.洛谷P1047 [NOIP2005 普及组]校门外的树5.洛谷P5728 【深基5.例5】旗鼓相当的对手6.洛谷P5721 【深基4.例6】数字直角三角形7.洛谷[NOIP2015 普及组] 金币8.洛谷[NOIP2011 普及组]数字反转9.洛谷P4956 [COCI2017-2018#6] Davor10.洛谷B3843 [GESP202306 三级]密码合规11.洛谷P1601 A+B Problem(高精度加法)
12.洛谷P1614 爱与愁的心痛(滑动窗口解法)
13.洛谷P2670 [NOIP2015 普及组] 扫雷游戏14.洛谷P1563 [NOIP2016 提高组] 玩具谜题15.洛谷B3849 [GESP样题 三级] 进制转换16.洛谷P1100 高低位交换17.洛谷P1143 进制转换18.[NOIP2008 提高组] 笨小猴(洛谷题号P1125)19.洛谷[NOIP2015 普及组] 金币20.洛谷P3383 【模板】线性筛素数21.洛谷P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题22.洛谷B3940 [GESP样题 四级] 填幻方23.洛谷P1042 [NOIP2003 普及组] 乒乓球24.洛谷P1067 [NOIP2009 普及组] 多项式输出25.洛谷P1098 [NOIP2007 提高组] 字符串的展开26.洛谷P1842 [USACO05NOV] 奶牛玩杂技27.洛谷P1223 排队接水28.洛谷P1209修理牛棚 Barn Repair29.洛谷P5250 【深基17.例5】木材仓库30.洛谷P1226 【模板】快速幂31.洛谷P1480 A/B Problem32.洛谷P1786 帮贡排序33.双指针习题:Kalindrome Array爱与愁的心痛
题目背景
(本道题目隐藏了两首歌名,找找看哪~~~)
《爱与愁的故事第一弹·heartache》第一章。
《我为歌狂》当中伍思凯神曲《舞月光》居然没赢给萨顶顶,爱与愁大神心痛啊~~~而且最近还有一些令人伤心的事情,都让人心痛(最近真的很烦哈)……
题目描述
最近有 n 个不爽的事,每句话都有一个正整数刺痛值(心理承受力极差)。爱与愁大神想知道连续 m 个刺痛值的和的最小值是多少,但是由于业务繁忙,爱与愁大神只好请你编个程序告诉他。
输入格式
第一行有两个用空格隔开的整数,分别代表 n 和 m。
第 2 到第 (n + 1) 行,每行一个整数,第 (i + 1) 行的整数 ai 代表第 i 件事的刺痛值 ai。
输出格式
输出一行一个整数,表示连续 m 个刺痛值的和的最小值是多少。
样例 #1
样例输入 #1
8 3 1 4 7 3 1 2 4 3
样例输出 #1
6
提示
数据规模与约定
- 对于 30% 的数据,保证 n <=20
- 对于 60% 的数据,保证 n <=100。
- 对于 90% 的数据,保证 n <=10^3.
- 对于 100% 的数据,保证 0<=m<=n<=3*10^3;1<=ai<=100
这题有什么思路?
这题拿到手我们就有一个极为暴力的思路,使用两层for循环遍历每一个m个数的组合,找出最小数,这样我们就可以直接解决问题了。但是,这种方法的时间复杂度为o(n^2),在数据量比较大的时候,我们对
元素操作的次数太多了,可能效率会非常低。这时候我们可以考虑使用滑动窗口的解法。
滑动窗口
所谓滑动窗口,顾名思义,他就是像一个滑动的窗口,来遍历数组,可以在一个for循环内完成两个for循环需要完成的事情。
我们可以先记录一下a[0]-a[m-1],这m个元素的和,然后将滑动窗口一个一个元素向后移,比较当前组合和最小的m个元素之和的大小,并且实时更新:
//使用CurrentSum变量来储存当前m个数的和 int CurrentSum = 0; //先计算前m个数的和 for (int i = 0; i < m; i++) CurrentSum += a[i]; //m个数的和的最小值 int minSum = CurrentSum;
C++代码如下:
#include<vector> #include<iostream> using namespace std; int main() { //输入数据 int n, m; cin >> n >> m; //定义a数组,存储n个数 vector<int> a(n); for (int i = 0; i < n; i++) cin >> a[i]; //使用CurrentSum变量来储存当前m个数的和 int CurrentSum = 0; //先计算前m个数的和 for (int i = 0; i < m; i++) CurrentSum += a[i]; //m个数的和的最小值 int minSum = CurrentSum; //从第m+1个数开始,滑动窗口开始移动 for (int i = m; i < n; i++) { //滑动窗口加上现在这个元素,减去最后面那个元素 CurrentSum += a[i] - a[i - m]; //minSum取这些组合里面的最小值 minSum = minSum > CurrentSum ? CurrentSum : minSum; } cout << minSum; return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战