单调队列

烽火传递 dp+单调队列

坚强是说给别人听的谎言 提交于 2019-11-27 00:09:22
题目大意 烽火台又称烽燧,是重要的军事防御设施,一般建在险要或交通要道上。一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息;夜晚燃烧干柴,以火光传递军情,在某两座城市之间有n个烽火台,每个烽火台发出信号都有一定代价。为了使情报准确地传递,在连续m个烽火台中至少要有一个发出信号。请计算总共最少花费多少代价,才能使敌军来袭之时,情报能在这两座城市之间准确传递。 分析 要用动态规划的方法解决。我们可以写出这样的方程f[i]:=min{f[j]}+a[i](i-m<=j<i-1)(因为要保证i之前的3个中必须存在被点亮的烽火台)。 那问题就变成了在f[i-m]到f[i-1]中找一个最小的。 单调队列可以很好地完成这个任务。 单调队列见—— 单调队列 代码 var a:array[0..1000001] of longint; d,v:array[0..1000001] of longint; f:array[0..1000001] of longint; head,tail:longint; i,j,k:longint; n,m:longint; ans:longint; begin readln(n,m); for i:=1 to n do readln(a[i]); fillchar(d,sizeof(d),0); fillchar(v,sizeof(v),0); head:=1;

dp(未完成)

六月ゝ 毕业季﹏ 提交于 2019-11-26 23:36:21
一、线性 1.简单示例 (1)LIS问题 (2)LCS问题 (3)数字三角形 二、背包 1.0/1背包 2.完全背包 3.多重背包(二进制拆分) 4.分组背包 三、区间 四、树形 1.背包类 2.二次扫描与换根法 五、环形与后效性处理 六、状态压缩 七、倍增优化 八、数据结构优化 九、单调队列优化 1.单调队列优化多重背包 十、斜率优化 十一、四边形不等式 1.一维线性 2.二维区间 十二、计数 十三、数位统计 来源: https://www.cnblogs.com/Moxingtianxia/p/11335339.html

Blue:贪心,单调队列

拟墨画扇 提交于 2019-11-26 19:32:14
考场上什么都没想。 显然在扯淡了,应该说是刚开始想了一些没用的。 有决策单调性,所以二分答案? 好,那就二分答案。想想怎么检查每只蛤能不能都跳到终点? 那么每只蛤都不能掉队啊。 如果你现在遇到了一个石头,你就会优先让最落后的那只蛤跳过来蛤。(因为都不能掉队啊) 如果它离的太远跳不过来了,那么这只蛤就永远地掉队了。 嗯,这个想法还是比较简单的吧。 然后我们可以发现这个思路貌似是普适的。我们现在去掉二分答案。 所以现在问题不再是检查是否都不掉队,而是直接询问有多少个蛤能过去。 继续上面的思路,让最落后的蛤尝试跳过来,跳不过来就放弃它去让第二落后的蛤来。 然后有了这个思路就可以愉快的AC了。 当然我们需要证明(我没看题解,我自己口胡蛤) 对于任意多的蛤,分别标号为1234...,按照它们目前所在的位置排序 那么现在突然出现了一个石头用0表示:1234...0 现在要用蛤来跳,按照刚才的策略你会让1跳得到234...1 其它决策无非就2种, 一种是这块石头所有蛤都无视它:这一定不优,如果你要忽视它还要跳到后面,那么你在这里歇一下脚再往后跳当然不会变差啦 另一种就是让不是最落后的蛤跳到上面:你会得到12x4...3之类的(x表示被踩沉了的石头) 相较于最优决策,区别就是有一只还在原来的最落后位置,而最优决策下有一只蛤更靠前了一点(至少不再是那个最落后位置了)

DP&图论 DAY 3 上午

守給你的承諾、 提交于 2019-11-26 17:22:32
DP&图论 DAY 3 上午 状态压缩 dp >状态压缩 dp ◦ 状态压缩是设计 dp 状态的一种方式。 ◦ 当普通的 dp 状态维数很多(或者说维数与输入数据有关),但每一维总 量很少是,可以将多维状态压缩为一维来记录。 ◦ 这种题目最明显的特征就是: 都存在 某一给定信息的范围非常小 (在 20 以内),而我们在 dp 中所谓压缩的就是这一信息。 ◦ (或者是在做题过程中分析出了某一信息种类数很少) ◦ 我们来看个例子。 > 经典题 ◦ 给出一个 n*m 的棋盘,要放上一些棋子,要求不能有任意两个棋子相邻。 求方案数。 ◦ n<=100; ◦ m<=8 。 >Solution dp[i][0/1][0/1]....[0/1] 第 i 行每一列的状态0/1 然后考虑第i+1行,如果不冲突,转移 然后发现多维可以压缩成一个数dp[i][s] dp[i][s]-->dp[i+1][s'] s‘和s不冲突,&一下=0 ◦ 我们发现这个 m 是非常小的,这样就可以启发我们对每一行 2^m 状态压缩。 ◦ 设 dp[i][S] 表示到了第 i 行,第 i 行的状态是 S 的方案数是多少。 ◦ 其中 S 的第 j 位为 1 ,表示 i 这行第 j 位放了一个棋子。 ◦ 状态转移: dp[i][S]=sigema {dp[i-1][ S' ] | S&S' ==0 } 。 ◦

hdu2430Beans(单调队列)

一个人想着一个人 提交于 2019-11-26 16:02:48
Mr. Pote's shop sells beans now. He has N bags of beans in his warehouse, and he has numbered them with 1, 2, …, N according to their expired dates. The i-th bag contains Wi units of beans. For selling at retail makes only a little profit, Mr. Pote want to pack beans in small packets with certain size and sell them in packets. Here comes his packing way: Suppose the size of the packet is P units. Firstly, Mr. Pote selects some bags (at least one) of beans with consecutive number in his warehouse. Then he takes out the beans from all selected bags, and puts them together on the desktop. To pack

DAY 3 上午

拜拜、爱过 提交于 2019-11-26 14:13:36
状压DP 状态压缩dp 状态压缩是设计dp状态的一种方式。 当普通的dp状态维数很多(或者说维数与输入数据有关),但每一维总量很少时,可以将多维状态压缩为一维来记录。 这种题目最明显的特征就是:都存在某一给定信息的范围非常小(在20以内),而我们在dp中所谓压缩的就是这一信息。 (或者是在做题过程中分析出了某一信息种类数很少) 我们来看个例子。 经典题 ◦给出一个n*m的棋盘,要放上一些棋子,要求不能有任意两个棋子相邻。求方案数。 ◦ n<=100; ◦m<=8。 如果m固定的话可以设f[i][0/1][0/1]...[0/1]表示每一行每一列放不放 如果不是固定的呢? 我们发现后面的多个0/1可以看成一个二进制数 那我们不就可以用数字代替后面的维数吗? f[i][s]->f[i+1][s’](s&s’==0) 你会发现这样记录很暴力,状态数是与m相关的指数级的,但同时也就是因为m小我们就确实可以这么做。 其实本质就是很暴力的记录状态,只不过利用了题目本身的特殊条件(这一维很小),使得我们并不会因此复杂度过高。 同时也就是说,如果题目本身没有这样一个较小的信息,就不能应用状态压缩。 所以在接下来的题目中大家可以更注意一下题目所给的条件。 状态压缩dp肯定是有一维是指数级的,这正是状态压缩的特点。 BZOJ1087 互不侵犯 在n*n的棋盘上放置k个国王,使得任意两个国王互相不攻击

滑动窗口【单调队列】

筅森魡賤 提交于 2019-11-26 12:31:53
给定一个大小为n≤106的数组。 有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。 您只能在窗口中看到k个数字。 每次滑动窗口向右移动一个位置。 以下是一个例子: 该数组为[1 3 -1 -3 5 3 6 7],k为3。 窗口位置 最小值 最大值 [1 3 -1] -3 5 3 6 7 -1 3 1 [3 -1 -3] 5 3 6 7 -3 3 1 3 [-1 -3 5] 3 6 7 -3 5 1 3 -1 [-3 5 3] 6 7 -3 5 1 3 -1 -3 [5 3 6] 7 3 6 1 3 -1 -3 5 [3 6 7] 3 7 您的任务是确定滑动窗口位于每个位置时,窗口中的最大值和最小值。 输入格式 输入包含两行。 第一行包含两个整数n和k,分别代表数组长度和滑动窗口的长度。 第二行有n个整数,代表数组的具体数值。 同行数据之间用空格隔开。 输出格式 输出包含两个。 第一行输出,从左至右,每个位置滑动窗口中的最小值。 第二行输出,从左至右,每个位置滑动窗口中的最大值。 输入样例: 8 3 1 3 -1 -3 5 3 6 7 输出样例: -1 -3 -3 -3 3 3 3 3 5 5 6 7 窗口可以用队列维护, 3,-1,-3,最小值为-3,只要有-3存在,3,-1就不会被用到,删去; 成为一个单调递增的队列,对头为最小值 #include<iostream>

【学习笔记】动态规划—各种 DP 优化

雨燕双飞 提交于 2019-11-26 09:20:18
【学习笔记】动态规划—各种 DP 优化 【大前言】 个人认为贪心, \(dp\) 是最难的,每次遇到题完全不知道该怎么办,看了题解后又瞬间恍然大悟(TAT)。这篇文章也是花了我差不多一个月时间才全部完成。 【进入正题】 用动态规划解决问题具有 空间耗费大 、 时间效率高 的特点,但也会有时间效率不能满足要求的时候,如果算法有可以优化的余地,就可以考虑时间效率的优化。 【DP 时间复杂度的分析】 \(DP\) 高时间效率的关键在于它减少了“ 冗余 ”,即不必要的计算或重复计算部分,算法的冗余程度是决定算法效率的关键。而动态规划就是在将问题规模不断缩小的同时,记录已经求解过的子问题的解,充分利用求解结果,避免了反复求解同一子问题的现象,从而减少“ 冗余 ”。 但是,一个动态规划问题很难做到完全消除“ 冗余 ”。 下面给出动态规划时间复杂度的决定因素: 时间复杂度 \(=\) 状态总数 \(×\) 每个状态转移的状态数 \(×\) 每次状态转移的时间 【DP 优化思路】 一:减少状态总数 \((1).\) 改进状态表示 \((2).\) 选择适当的规划方向 二:减少每个状态转移的状态数 \((1).\) 四边形不等式和决策的单调性 \((2).\) 决策量的优化 \((3).\) 合理组织状态 \((4).\) 细化状态转移 三:减少状态转移的时间 \((1).\) 减少决策时间 \(

dp单调队列优化

╄→尐↘猪︶ㄣ 提交于 2019-11-25 16:53:43
dp单调队列优化 \(dp[i]=\max/\min(dp[j])+c[i]\) for example: \(dp[i]=\min(dp[j])+c[i]\) 考虑两个决策 \(p,q(p<q)\) ,若 \(dp[p]>=dp[q]\) ,则决策永远不可能为 \(p\) 。这是因为 \(dp[p]\) 的值 没有 \(dp[q]\) 优 ,同时比 \(q\) 离开决策范围更快。总之, \(q\) 的 生存能力更强 。 简单来讲, 维护单调递增的一组决策 template <typename T> struct dequeue { vector <T> q; ll l,r; void init(int n) { q.resize(n); l=0,r=0; } bool empty() { return l>=r; } T back() { return q[r]; } T front() { return q[l]; } void pop_front() { l++; } void pop_back() { r--; } void push_back(T k) { q[++r]=k; } void insert(T k) { while (l<=r&&back().first<=k.first) pop_back(); push_back(k); } }; 定义: dequeue