newcoder H肥猪(单调队列 / 线段树)题解
题意:
小B来到了一个异世界,成为了肥猪之王。
在这个异世界,共有n种肥猪,编号分别为1,...,n。
小B希望集齐这n种肥猪。
召集肥猪有两种方式:
1. 花费a[i]的金币召唤一只编号为i的肥猪。
2. 花费x的金币使所有已召集的肥猪进化。
即编号为i的肥猪编号变成i+1,特殊的,编号为n的肥猪编号变成1。
请问小B最少要花多少金币才能集齐n种肥猪。
链接:https://ac.nowcoder.com/acm/contest/332/H
来源:牛客网
思路(官方):
从0到n-1枚举第二种操作的使用次数step,那么对于最终得到的编号为i的肥猪,假如它是召唤编号为j的肥猪然后进化多次得到的,则一定有 i−step≤j≤ii−step≤j≤i ,并且这是充要的,即它可以由这个区间的任何一个j召唤后进化多次得到。因此只用这个区间的a[j]的最小值就是得到i的代价。把所有i的代价相加再加上step*x就是step对应的最小代价。注意,这个题目是一个环而不是链,这只需要将a复制一份即可。求区间最小值有很多方法,比如单调队列。时间复杂度 O(n2) 。
之前我自己想的是直接找生成每一个点的最小代价(a[k] + step * x),然后保存最大步长,但是这里有个问题,就是我这个step其实是公用的,按照我原来的思路用a[k] + step * x去找最小代价,那么其实是误判了最佳情况,所以wa了orz
单调队列好久没写了...凑活写了一下...
代码:
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = + ;
const int MOD = 1e9 + ;
const ll INF = 1e19;
ll a[maxn << ], q[maxn << ], pos[maxn << ]; //递增队列
ll n, x; int main(){
scanf("%lld%lld", &n, &x);
for(int i = ; i < n; i++){
scanf("%lld", &a[i]), a[n + i] = a[i];
}
ll ans = INF;
for(int step = ; step <= n - ; step++){
int head = , tail = ;
ll ret = ;
for(int i = n - step; i < n; i++){
while(head < tail && q[tail - ] >= a[i]) tail--;
q[tail] = a[i];
pos[tail++] = i;
}
for(int i = n; i < n + n; i++){
while(head < tail && q[tail - ] >= a[i]) tail--;
q[tail] = a[i];
pos[tail++] = i;
while(head < tail && pos[tail - ] - pos[head] > step) head++;
ret += q[head];
}
ret = ret + step * x;
ans = min(ans, ret);
}
printf("%lld\n", ans);
return ;
}
newcoder H肥猪(单调队列 / 线段树)题解的更多相关文章
- POJ 2823 Sliding Window(单调队列 || 线段树)题解
题意:求每个长度为k的数组的最大值和最小值 思路: 1.用线段树创建维护最大值和最小值,遍历询问,简单复习了一下...有点手生 2.单调队列: 可以看一下详解 单调队列顾名思义就是一个单调递增或者递减 ...
- [洛谷P1886]滑动窗口 (单调队列)(线段树)
---恢复内容开始--- 这是很好的一道题 题目描述: 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口. 现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的 ...
- [luoguP1440] 求m区间内的最小值(单调队列 || 线段树)
传送门 这种水题没必要搞线段树了,单调队列就行啊. ——代码 #include <cstdio> ; , t = ; int a[MAXN], q[MAXN]; int main() { ...
- HDU 4122 Alice's mooncake shop (单调队列/线段树)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4122 题意:好难读懂,读懂了也好难描述,亲们就自己凑合看看题意把 题解:开始计算每个日期到2000/1/ ...
- poj3162 树形dp|树的直径 + 双单调队列|线段树,好题啊
题解链接:https://blog.csdn.net/shiqi_614/article/details/8105149 用树形dp是超时的,, /* 先求出每个点可以跑的最长距离dp[i][0|1] ...
- BZOJ 1012: [JSOI2008]最大数maxnumber 单调队列/线段树/树状数组/乱搞
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 4750 Solved: 2145[Submi ...
- 【P1886】滑动窗口(单调队列→线段树→LCT)
这个题很友好,我们可以分别进行简单难度,中等难度,恶心难度来做.然而智商没问题的话肯定是用单调队列来做... 板子题,直接裸的单调队列就能过. #include<iostream> #in ...
- 洛谷P4198 楼房重建 单调栈+线段树
正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...
- 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)
2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...
随机推荐
- c++ 各种类型转换
1.int 2 string 法1:c++11里面的to_string #include <string> std::); //or auto s = std::to_string(); ...
- CSS radial-gradient() 函数实现渐变
值 描述 shape 确定圆的类型: ellipse (默认): 指定椭圆形的径向渐变. circle :指定圆形的径向渐变 size 定义渐变的大小,可能值: farthest-corner (默认 ...
- sublime text3配置及相关小技巧
1.下载&安装: 官方地址:http://www.sublimetext.com/,sublime text3又更新了,支持不依赖插件进行侧边栏颜色的更改,同时自带的皮肤颜色也有四种,十分方便 ...
- Vue系列之 => 自定义键盘修饰符
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Yii Restful api自定义字段
- laravel中使用的PDF扩展包——laravel-dompdf和laravel-snappy
这两天项目中需要将HTML页面转换为PDF文件方便打印,我在网上搜了很多资料.先后尝试了laravel-dompdf和laravel-snappy两种扩展包,个人感觉laravel-snappy比较好 ...
- c++学习笔记(八)- map
map<key, value>是按key排好序的,key不可以重复. 1. map.lower_bound():按key查找,如果查找的key存在,返回该位置,如果不存在返回大于所查找值的 ...
- HDU 1232 畅通工程 (并查集)
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可). ...
- Codeforce 733B - Parade (枚举)
Very soon there will be a parade of victory over alien invaders in Berland. Unfortunately, all soldi ...
- Codeforce 270A - Fancy Fence (正多边形)
Emuskald needs a fence around his farm, but he is too lazy to build it himself. So he purchased a fe ...