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中有多 ...
随机推荐
- PE结构图示
- uvalive 3887 Slim Span
题意: 一棵生成树的苗条度被定义为最长边与最小边的差. 给出一个图,求其中生成树的最小苗条度. 思路: 最开始想用二分,始终想不到二分终止的条件,所以尝试暴力枚举最小边的长度,然后就AC了. 粗略估计 ...
- python之小数据池
代码块 Python 程序 是由代码块构造的.块是一个python程序的文本,它是作为一个执行单元的. 代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块. 而作为交互方式输入的每个命令都是 ...
- 20165215 学习基础和c语言基础调查
学习基础和c语言基础调查 <做中学>读后感与技能学习心得 读后感 Don't watch the clock. Do what it does. Keep going. 不要只看时钟,要效 ...
- Linux基础命令---显示域名ypdomainname
ypdomainname ypdomainname指令显示由函数“getdomainname”返回的主机域名,使用这个指令也可以设置一个主机NIS/YP域名. 此命令的适用范围:RedHat.RH ...
- AtCoder Beginner Contest 082 A - Round Up the Mean
题目链接:https://abc082.contest.atcoder.jp/tasks/abc082_a Time limit : 2sec / Memory limit : 256MB Score ...
- bzoj3678 简单题
题目链接 bitset #include<algorithm> #include<iostream> #include<cstdlib> #include<c ...
- [转载] Web Service工作原理及实例
一.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求, ...
- linux centos6.5 php5.6 安装PHPUnit 5.2.9 (转)
转自:http://blog.csdn.net/shancunxiaoyazhi/article/details/50765293 操作系统版本:CentOS6.5 PHP版本:5.6 下载phpun ...
- eHR自动同步获取LDAP中的邮箱地址
背景:公司里有eHR系统,有网域,IBM Lotus Notes邮件系统,新人入职会在eHR系统里提前建好档案,网域帐号.邮箱帐号均会在入职前提前建好,因为邮箱帐号是晚于eHR建档的,因此在eHR建档 ...