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

(单调队列优化)洛谷P2627 USACO11OPEN Mowing the Lawn / P3572 POI2014 Little Bird 题解

用来复健单调队列优化 dp 的,对它也加深了一些理解。

1.Mowing the Lawn

题意

在一年前赢得了小镇的最佳草坪比赛后,Farmer John 变得很懒,再也没有修剪过草坪。现在,新一轮的最佳草坪比赛又开始了,Farmer John 希望能够再次夺冠。

然而,Farmer John 的草坪非常脏乱,因此,Farmer John 只能够让他的奶牛来完成这项工作。Farmer John 有 nnn1≤n≤1051\le n\le 10^51n105)只排成一排的奶牛,编号为 1∼n1\sim n1n。每只奶牛的效率是不同的,奶牛 iii 的效率为 aia_iai0≤ai≤1090\le a_i\le 10^90ai109)。

靠近的奶牛们很熟悉,因此,如果 Farmer John安排超过 KKK 只连续的奶牛,那么,这些奶牛就会罢工去开派对。因此,现在 Farmer John 需要你的帮助,计算 FJ 可以得到的最大效率,并且该方案中没有连续的超过 kkk 只奶牛。

思路

fi,opf_{i,op}fi,op 表示,第 iii 头奶牛选(op=1op=1op=1)或不选(op=0op=0op=0)的方案数。那么:
fi,0=max⁡(fi−1,0,fi−1,1)fi,1=max⁡{fj,0+si−sj},i−j≤k\begin{matrix} f_{i,0}=\max(f_{i-1,0},f_{i-1,1})\\ f_{i,1}=\max\{f_{j,0}+s_i-s_j\},i-j\le k \end{matrix}fi,0=max(fi1,0,fi1,1)fi,1=max{fj,0+sisj},ijk

其中 sis_isi 表示 ∑k=1iak\displaystyle\sum_{k=1}^i a_kk=1iak

对于 fi,1=max⁡{fj,0+si−sj}f_{i,1}=\max\{f_{j,0}+s_i-s_j\}fi,1=max{fj,0+sisj}sis_isi 提出来得到:fi,1=si+max⁡{fj,0−sj}f_{i,1}=s_i+\max\{f_{j,0}-s_j\}fi,1=si+max{fj,0sj}。还有个限制等价为 j≥i−kj\ge i-kjik,发现限制单调递增。因此可以用单调队列维护决策点 jjj

回忆一下单调队列优化 dp 的基本步骤:弹出越界队首、加入所需元素、获取答案。每次最优决策点取队首,加入新决策点进队尾:

  • q[head]<i−kq[head]<i-kq[head]<ik 就弹出队首;
  • f[q[tail]][0]−s[q[tt]]<f[i][0]−s[i]f[q[tail]][0]-s[q[tt]]<f[i][0]-s[i]f[q[tail]][0]s[q[tt]]<f[i][0]s[i] 说明队尾不如决策 iii 更优,因此弹出队尾。

答案就是 max⁡(fn,0,fn,1)\max(f_{n,0},f_{n,1})max(fn,0,fn,1)

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e5+9;
ll n,k,a[N];
ll s[N],q[N],f[N][2];
int main()
{scanf("%lld%lld",&n,&k);for(int i=1;i<=n;i++){scanf("%lld",&a[i]);s[i]=s[i-1]+a[i];}ll hh=0,tt=0;for(int i=1;i<=n;i++){f[i][0]=max(f[i-1][0],f[i-1][1]);while(hh<=tt&&q[hh]<i-k)hh++;f[i][1]=f[q[hh]][0]+s[i]-s[q[hh]];while(hh<=tt&&f[q[tt]][0]-s[q[tt]]<f[i][0]-s[i])tt--;q[++tt]=i;}printf("%lld",max(f[n][0],f[n][1]));return 0;
}

2.Little Bird

题意

nnn 棵树排成一排,第 iii 棵树的高度是 did_idi

qqq 只鸟要从第 111 棵树到第 nnn 棵树。当第 iii 只鸟在第 jjj 棵树时,它可以飞到第 j+1,j+2,⋯ ,j+kij+1, j+2, \cdots, j+k_ij+1,j+2,,j+ki 棵树。

如果一只鸟飞到一颗高度大于等于当前树的树,那么它的劳累值会增加 111,否则不会。由于这些鸟已经体力不支,所以它们想要最小化劳累值。

1≤n≤1061 \le n \le 10^61n1061≤di≤1091 \le d_i \le 10^91di1091≤q≤251 \le q \le 251q251≤ki≤n−11 \le k_i \le n - 11kin1

思路

fif_ifi 表示鸟飞到第 iii 棵树的最小劳累值。那么:
fi=min⁡{fj+[aj≤ai]},i−j≤kf_i=\min\{f_j+[a_j\le a_i]\},i-j\le kfi=min{fj+[ajai]},ijk

同样将限制转化为 j≥i−kj\ge i-kjik,限制单调递增,用单调队列维护决策点。

  • q[head]<i−kq[head]<i-kq[head]<ik 就弹出队首;
  • f[q[tail]]+[a[q[tail]]≤ai]>fif[q[tail]]+[a[q[tail]]\le a_i]>f_if[q[tail]]+[a[q[tail]]ai]>fi,比更新后的当前值小,直接推出队尾。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e6+9;
ll n,a[N],Q;
ll f[N],q[N];
int main()
{scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);scanf("%lld",&Q);while(Q--){memset(f,0,sizeof(f));memset(q,0,sizeof(q));ll k;scanf("%lld",&k);ll hh=0,tt=0;q[0]=1;for(int i=2;i<=n;i++){while(hh<=tt&&q[hh]<i-k)hh++;f[i]=f[q[hh]]+(a[q[hh]]<=a[i]);while(hh<=tt&&f[q[tt]]+(a[q[tt]]<=a[i])>f[i])tt--;q[++tt]=i;}printf("%lld\n",f[n]);}return 0;
}
http://www.dtcms.com/a/272878.html

相关文章:

  • 《数据库》 MySQL库表操作
  • 磐维数据库panweidb集中式集群配置VIP【添加、删除和修改】
  • Chromium 引擎启用 Skia Graphite后性能飙升
  • websocket的客户端(发送接收json的消息)
  • vue3 td 标签优化时间显示
  • 穿梭时空的智慧向导:Deepoc具身智能如何赋予导览机器人“人情味”
  • 如何自动计算照片中光伏板数量:基于开源项目的自动识别光伏板计数解决方案
  • C++初阶-仿函数
  • 利萨如图形详解:原理与Python动态绘制
  • 数据库常见元数据表
  • .NET Framework 安装失败及异常情况 常用处理方法
  • 【前端】【Echarts】【Liquidfill 水球图】深入理解 ECharts Liquidfill 水球图:从入门到进阶
  • 解决飞牛 NAS 安装 OpenResty时的端口被占用问题!(如何解决飞牛Nas 80 443 端口被占用的问题)
  • C++ 模板参数展开
  • AI测试革命:从智能缺陷检测到自愈式测试框架的工业实践
  • 谷粒商城高级篇
  • 用GNU Radio生成Frank信号
  • Redisson 的分布式锁
  • 动态物体滤除算法
  • 全连接神经网络
  • AI教学设计助手:生成好教案的Prompt技术实战(二)
  • Java中实现线程安全的几种方式
  • 我做了一个在线工具导航网站!
  • Apache
  • 一招解决Win11桌面右键刷新BUG问题!
  • 高通跃龙IoT-IQ系列芯片深度解析:定位、特性与应用全景
  • 智能音视频-搭建可视化智能体
  • 机器学10——集成学习
  • 北京-4年功能测试2年空窗-报培训班学测开-第四十七天
  • 汽车功能安全-软件集成和验证(Software Integration Verification)【目的、验证输入、集成验证要求】9