刷题总结——烽火传递(单调队列+dp)
题目:
题目描述
烽火台又称烽燧,是重要的防御设施,一般建在险要处或交通要道上。一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息:夜晚燃烧干柴,以火光传递军情。在某两座城市之间有 n 个烽火台,每个烽火台发出信号都有一定的代价。为了使情报准确的传递,在 m 个烽火台中至少要有一个发出信号。现输入 n、m 和每个烽火台发出的信号的代价,请计算总共最少需要多少代价,才能使敌军来袭之时,情报能在这两座城市之间准确的传递!
输入格式
第一行有两个数 n,m 分别表示 n 个烽火台,在任意连续的 m 个烽火台中至少要有一个发出信号。
第二行为 n 个数,表示每一个烽火台的代价。
输出格式
一个整数,即最小代价。
样例数据 1
备注
【数据范围】
1<=n,m<=1,000,000,保证答案在 int 范围内。
1<=n,m<=1,000,000,保证答案在 int 范围内。
题解:
引用ssoj官方题解:
要用动态规划的方法解决。
我们可以写出这样的方程f[i]:=min{f[j]}+a[i](i-m<=j<i-1)
因为要保证i之前的3个中必须存在被点亮的烽火台。单纯这样循环会造成超时。
我们想到了用单调队列进行优化,由于随着i的循环,每次只有一个i进入决策区间也只有一个i出决策区间,由于每次选取决策区间中的最小值,所以维护一个单调递增序列,每次取出队首元素即可。
为什么可以将队尾元素无情的删去呢?由于后进队的序列同时满足在原序列中的位置更靠后和其在动态规划中的价值更大。这样选取这个元素就要比选取之前的任何一个决策要优,所以之前被删掉的决策都是无用的。
这道题的本质就是用单调队列维护了决策本身的价值和其在原序列中位置的同时单调。
要特别注意单调队列中的值是决策在原决策序列中的位置。
第一次见dp可以用单调队列搞的····牛逼
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int inf=1e+;
const int N=1e6+;
int n,m,w[N];
int que[N],head,tail,dp[N];
inline int R()
{
int f=;
char c;
for(c=getchar();(c<''||c>'');c=getchar());
for(;c>=''&&c<='';c=getchar())
f=(f<<)+(f<<)+c-'';
return f;
}
int main()
{
//freopen("a.in","r",stdin);
n=R(),m=R();
for(int i=;i<=n;i++)
w[i]=R();
head=,tail=;
dp[]=w[];
que[]=;
int temp=inf;
for(int i=;i<=m;i++)
dp[i]=min(temp,w[i]);
for(int i=;i<=n;i++)
{
if(i>m)
dp[i]=dp[que[head]]+w[i];
tail++;
while(dp[i]<=dp[que[tail-]]&&tail>head) tail--;
que[tail]=i;
if(que[tail]-que[head]>=m) head++;
}
int ans=inf;
for(int i=n;i>=n-m+&&i>=;i--)
ans=min(ans,dp[i]);
cout<<ans<<endl;
return ;
}
刷题总结——烽火传递(单调队列+dp)的更多相关文章
- 【LOJ#10180】烽火传递 单调队列+dp
题目大意:给定一个 N 个非负整数数组成的序列,每个点有一个贡献值,现选出其中若干数,使得每连续的 K 个数中至少有一个数被选,要求选出的数贡献值最小. 题解:设 \(dp[i]\) 表示考虑了序列前 ...
- [NOIP2010初赛]烽火传递+单调队列详细整理
P1313 [NOIP2010初赛]烽火传递 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 烽火台又称烽燧,是重要的防御设施,一般建在险要处或交通要道上 ...
- 刷题向》POJ2823 单调队列裸题(<不会做,请自裁>系列)
最近BZOJ炸了,而我的博客上又更新了一些基本知识,所以这里刷一些裸题,用以丰富知识性博客 POJ2823 滑动的窗口 这是一道经典的单调队题,我记得我刚学的时候就是用这道题作为单调队列的例题,算 ...
- [TyvjP1313] [NOIP2010初赛]烽火传递(单调队列 + DP)
传送门 就是个单调队列+DP嘛. ——代码 #include <cstdio> ; , t = , ans = ~( << ); int q[MAXN], a[MAXN], f ...
- zstu 4237 马里奥的求救——(单调队列DP)
题目链接:http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4237 这题可以转化为每次可以走g~d+x步,求最大分数,且最大分数的步数最少. ...
- POJ 3017 单调队列dp
Cut the Sequence Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8764 Accepted: 2576 ...
- 1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP
1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP 题意 用摄像机观察动物,有两个摄像机,一个可以放在奇数天,一个可以放在偶数天.摄像机在 ...
- 【CF1077F2】Pictures with Kittens 单调队列+dp
题目大意:给定一个长度为 N 的序列,点有点权,从序列中选出恰好 X 个数,并且保证任意连续的 K 个数中均有一个被选中,求选出的点权最大是多少. 题解:此题可以作为 烽火传递+ 来处理,只不过在烽火 ...
- POJ 1821 单调队列+dp
题目大意:有K个工人,有n个墙,现在要给墙涂色.然后每个工人坐在Si上,他能刷的最大范围是Li,且必须是一个连续子区间,而且必须过Si,他刷完后能获得Pi钱 思路:定义dp[i][j]表示前i个人,涂 ...
随机推荐
- MySQL存储过程简介和引擎说明
- POJ 1655 Balancing Act (树的重心,常规)
题意:求树的重心,若有多个重心,则输出编号较小者,及其子树中节点最多的数量. 思路: 树的重心:指的是一个点v,在删除点v后,其子树的节点数分别为:u1,u2....,设max(u)为其中的最大值,点 ...
- 洛谷 P1734 最大约数和
题目描述 选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大. 输入输出格式 输入格式: 输入一个正整数S. 输出格式: 输出最大的约数之和. 输入输出样例 输入样例#1: 1 ...
- UVA 10735 Euler Circuit (最大流)
题意:求混合图的欧拉路径. 一句话总结:网络流,最主要在于建图,此题是将出度则是和流量联系在了一起,用最大流来调整边的指向. 分析: 这题的困难之处在于无向边只能用一次,相当于一个方向未定的有向边. ...
- poj1338 Ugly Numbers 打表, 递推
题意:一个数的质因子能是2, 3, 5, 那么这个数是丑数. 思路: 打表或者递推. 打表: 若该数为丑数,那么一定能被2 或者3, 或者5 整除, 除完之后则为1. #include <ios ...
- PyCharm如何配置断点调试功能
1. 点击菜单 PyCharm -> Preferences.. 2. 在左侧菜单栏找到Project:Django - > Project Interpreter 并点击配置 Proje ...
- Bootstrap历练实例:超小的按钮
<!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...
- Avada v5.0.6 最新版本破解教程如下:
Avada v5.0.6 最新版本破解教程如下: .找到\themes\Avada\includes\avada-envato-api.php文件,注释掉如下两行代码 $response_code = ...
- base64类
public class Base64{ /** * how we separate lines, e.g. \n, \r\n, \r etc. */ private String lineSepar ...
- mongodb详细教程
转自:https://www.cnblogs.com/liruihuan/tag/MongoDB/