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

P5186 [COCI 2009_2010 #4] OGRADA

Luogu 题目传送门

双倍经验,一摸一样的题:Luogu 题目传送门2

这是我的一个有趣的做题故事,在洛谷打完卡(运势 § 凶 § )后,随机跳转一题,并到了这一题。

\(\;\)

题目大意

一个叫 Matija 的人打算用一个为 X 大小的滚筒刷一个栅栏。其中,这个栅栏是由 N 条木板,从左到右依次编号为 1…N,i 号木板的高度为 \(h_i\)。 Matija 是从上往下尽可能的刷最大面积的漆,剩下刷不到的面积用牙刷☠️刷。我们需要求出用牙刷 「涂」 的面积+在满足 「涂」 的面积最少的情况下,他最少要用滚筒刷 「刷」 多少次。

输入样例:

5 3
5 3 4 4 5

样例

一共有 5 个板子,高度分别为:5 3 4 4 5, 和一个刷子大小为 3 。Matija 会用刷子两次刷1号、2号、3号板子 \(3\) 格子的高度 和 3号、4号、5号板子 \(4\) 格子的高度。剩下的面积为 \(3\) 格子。

输出为:

3
2

算法!

用滑动窗口!

P1886 滑动窗口模板传送门

把问题分成两个 Parts。

Part 1

首先我们做一个行列式叫做 d ,然后从 1 到 N 遍历一遍,每次查询 a[i] 的时候检查 d 里的第一块木板 d.front() 移除木板如果超出窗口范围,i-d.front()+1为窗口大小。

if (!d.empty()&&i-d.front()+1>X) d.pop_front();

\(\;\)

然后移除全部 ≥ a[i] 的木板。有些人问为什么要这样做,答:这样可以维持第一块木板 d.front() 在本次窗口最小,相当于 \(min(a[i]) \; \{i\sim i+k-1\}\)

while (!d.empty()&&a[d.back()]>=a[i]) d.pop_back();

\(\;\)

if (i>=X) 表明可以开始刷了,用 window[i] 记录当前窗口最小值(换句话说:当前窗口的有效高度)。当前窗口的有效高度 \(\ast\) 刷子的长度 = 每个木板能涂的最大高度: window[i]*X。但是每个窗口大概率会有重叠的部分,比如像以下照片。
重叠

\(\;\)

这两个虚线画的为两个窗口,被涂的部分为重叠部分。重叠部分算法为选更矮的木板 min (新的木板高度,上一个窗口的有效高度) 乘以重叠部分的长度 X-1

min(window[i-1],window[i])*(X-1)

最后在用总长度 - 刚刚计算出来的长度就是第一小问的答案:high-num

\(\;\)

Part 2

用测试样例我们得到的 windows[0,0,3,3,4]

但是这不是每个板子的有效高度,比如 1 号板子有效高度是 3 不是 0, 3号、4号板子 有效高度是 4 而不是 3 。

如果仔细看,会发现 2 \(\ast\) k-1 个连起来的板子的中间板子,列如 i ~ i+2 \(\ast\) k-1 号板子的第 i+k号板子的有效高度是为 min(a[i]) {i~i+2 \(\ast\) k-1}。

而且在 Part 1 我们已经得到了每个窗口左边的有效高度,所以我们只需要从右往左查询一边把 window[i] 设为 min(window[j]) {j-k~j \(\leq\) i}。这样就可以把 windows 改成每个木板的有效高度 [3,3,4,4,4]

code:

for (int i=N;i>=1;i--){if (!d2.empty()&&d2.front()-i+1>X) d2.pop_front();while (!d2.empty() && window[d2.back()]<=window[i])d2.pop_back();d2.push_back(i);window2[i]=window[d2.front()];
}

最后,我们知道了每个位置要刷的高度,要求刷的次数。则用贪心可求出:

  1. \(window[i] \neq window[i+1]\;\) ans++
  2. 每隔 k 个窗口\(\;\) ans++

最后的最后,不开 long long 见祖宗!

时间复杂度:O(3N) = O(N)

废话不多说,代码直接上

完整代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e6;int N,X,a[maxn],high,window[maxn],window2[maxn],num,ans,cnt;signed main() {cin>>N>>X;for (int i=1;i<=N;i++) cin>>a[i],high+=a[i];deque<int> d,d2;for (int i=1;i<=N;i++) {if (!d.empty()&&i-d.front()+1>X) d.pop_front();while (!d.empty()&&a[d.back()]>=a[i]) d.pop_back(); // 移除比最后一个长的d.push_back(i); // 新的if (i>=X) {window[i]=a[d.front()];num+=window[i]*X;num-=min(window[i-1],window[i])*(X-1);}}for (int i=N;i>=1;i--){if (!d2.empty()&&d2.front()-i+1>X) d2.pop_front();while (!d2.empty() && window[d2.back()]<=window[i]) d2.pop_back();d2.push_back(i);window2[i]=window[d2.front()];}cout<<high-num<<endl;num=-1;for (int i=1;i<=N;i++){if (window2[i]!=window2[i-1]||i>=num+X) {ans++;num=i;}}cout<<ans;return 0;
}

我的提交记录

That's ALL! 😃

http://www.zskr.cn/news/71197.html

相关文章:

  • (6)普中A2 51单片机矩阵键盘和密码锁 - 详解
  • 12月最新推荐!宠物饮水机方案商权威排行榜:聚焦智能健康养宠,IoT平台与专业品牌深度解析
  • 2025年上海注册公司费用及收费标准TOP5推荐:注册公司流
  • 2025年五大乳化泵服务厂商推荐排行榜,实力乳化泵供应商选择
  • 2025年度中国3PE防腐无缝钢管公司排名:诚信的酸洗钝化无
  • Experimental results of RSDK method
  • P2184 贪婪大陆
  • PbootCMS 网站常见报错及解决方法汇总
  • 手机射频阻抗匹配调试方法 - 详解
  • 2025年长三角十大方矩管加工厂推荐,矩形方矩管与20#方矩
  • 无味羽绒被推荐哪家?这几款从源头告别异味,敏感肌放心囤
  • 2025年断桥铝门窗五大品牌推荐,断桥铝门窗知名品牌全解析
  • 神经网络之正交矩阵 - 教程
  • lock_guard 与 unique_lock:一对“保安”与“管家”的互斥锁双人舞
  • 寒冬保暖羽绒被怎么选?这 5 个专业品牌带你解锁温暖睡眠新体验
  • 备婚 _ 结婚 _ 陪嫁 _ 乔迁必看!重要时刻5 大高性价比羽绒被品牌推荐
  • 基于势场法的多智能体机器人编队控制
  • 2025年12月真空袋厂家选择指南:权威维度横向评测解析
  • pbootcms内页子栏目当前栏目如何实现高亮显示(PbootCMS 内页子栏目当前栏目高亮显示的实现方法)
  • 2026年X射线防护服源头厂家推荐:射线防护服/铅衣防护服/医用 x 射线防护服公司品牌推荐
  • ANSYS 2025 R1 仿真算力升级 电子研发提速!ANSYS 2025 R1 下载安装教程 新版本核心优势速递
  • 2025年靠谱的电动缸源头工厂五大推荐,电动缸工厂选哪家全解
  • 2025年销量领先认证机构推荐:哪家更值得信赖?多维评估与案例比对
  • 2025靠谱的冷水机厂家TOP5权威推荐:化工冷水机核心选型
  • 2025年银川专业祛痣机构排名推荐,易己弘美容详细介绍、研发
  • LINQ查询表达式基础
  • 2025 年羽绒蓬松度天花板!这 5 家羽绒供应商凭什么征服高端市场?
  • 2025除尘羽绒工厂怎么选?这 5 家实力派企业值得关注
  • MATLAB归一化随机共振代码
  • 全球雇佣好帮手!国际 EOR 服务商推荐Safeguard Global,企业跨境雇佣不踩坑