当前位置: 首页 > 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.jsqmd.com/news/60658/

相关文章:

  • 2025年反应釜定制厂家实力推荐,看看哪家信誉好?
  • HTML5与CSS3 API文档及强大的技术书籍资源包
  • 2025年中国五大内磁喇叭厂家推荐:看哪家品质可靠
  • 2025年度口碑好的金相检测分析服务商TOP5权威推荐:看看
  • PbootCMS模板如何调用友情链接(PbootCMS友情链接调用指南:标签与参数详解)
  • 2025温汤镇温泉房产TOP5权威推荐:深度测评指南,甄选度
  • 2025年中国五大内磁喇叭工厂推荐:哪家口碑好?
  • 12月最新推荐!宠物饮水机方案商权威排行榜:聚焦智能健康养宠,IoT平台与专业品牌深度解析
  • 2025年上海注册公司费用及收费标准TOP5推荐:注册公司流
  • PbootCMS模板怎么嵌套引用其他模版文件(PbootCMS 模板嵌套引用其他模板文件的方法)
  • PbootCMS如何实现上传的文件使用原名称(PbootCMS 二开实现非图片文件使用原名称保存的方法)
  • 神州数码AP密码
  • 2025年五大乳化泵服务厂商推荐排行榜,实力乳化泵供应商选择
  • PbootCMS多选按钮前台页面如何循环|内容多选遍历(PbootCMS 多选按钮前台页面循环遍历方法)
  • 2025年五大靠谱的隔离式安全栅推荐,专业实力品牌全解析
  • 2025年惠州十大奢侈品名包回收店排行榜,推荐回收价高的奢侈
  • PBOOTCMS调用时间标签[list:data],怎么调用不显示小时、分、秒
  • 2025年惠州口碑好的民办高级中学排行榜,求推荐实力不错的民
  • 2025年度中国3PE防腐无缝钢管公司排名:诚信的酸洗钝化无
  • 2025年度冲锋衣棉服加工厂排名:冲锋衣棉服加工厂哪家售后
  • Experimental results of RSDK method
  • 2025年专业的工业噪声治理公司TOP5权威推荐:甄选企业助
  • 2025年度铁艺冲压配件十大优质生产厂排行榜,合作案例多的企
  • 2025年度北京冲锋衣棉服合作商排行榜:冲锋衣棉服加工厂哪家
  • 2025全国矿用橡套电缆公司排名 煤矿极端环境适用
  • P2184 贪婪大陆
  • PbootCMS 网站常见报错及解决方法汇总
  • 羽绒被品牌推荐:2025年十大口碑品牌测评与选购指南
  • 值得推荐的spc仿瓷墙板供应商TOP5:看哪家实力强?
  • 手机射频阻抗匹配调试方法 - 详解