BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】
Description
已知一个长度为n的序列a1,a2,...,an。
对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt(abs(i-j))
Input
第一行n,(1<=n<=500000)
下面每行一个整数,其中第i行是ai。(0<=ai<=1000000000)
Output
n行,第i行表示对于i,得到的p
Sample Input
6
5
3
2
4
2
4
Sample Output
2
3
5
3
5
4
决策单调性优化DP
。。。调了一晚上,都要自闭了
首先可以发现根号函数是一个增长越来越慢的函数
所以一个点如果不能对答案造成贡献,那么他永远都不能造成贡献了
然后就考虑怎么维护这个东西
首先正反跑两遍然后取max这个思路非常显然
现在可以考虑怎么维护单次的贡献
因为对于i,需要最大化
\(h_j - h_i + sqrt(i-j)\)
所以我们可以把原序列划分成一些区间
使得这些区间可以取到最大值
然后每次统计贡献直接在区间上查找就可以了
考虑维护一个队列来维护\([i,n]\)这个区间的所有最优区间
每个节点用三元组\([l,r,pos]\)表示
代表在\([l,r]\)这个区间里面pos可以贡献最大值
然后直接每次看一看如果当前新加入的节点是可以完全包含末尾区间,直接弹出,知道不能操作
这时如果序列为空直接加入\([i,n,i]\)
否则把最后一个区间划分成两个区间进行操作就可以了
注意统计贡献的时候参数顺序很重要
//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
//typename
typedef long long ll;
//convenient for
#define for_up(a, b, c) for (int a = b; a <= c; ++a)
#define for_down(a, b, c) for (int a = b; a >= c; --a)
#define for_vector(a, b) for (int a = 0; a < (signed)b.size(); ++a)
//inf of different typename
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
//fast read and write
template <typename T>
void Read(T &x) {
bool w = 1;x = 0;
char c = getchar();
while (!isdigit(c) && c != '-')c = getchar();
if (c == '-')w = 0, c = getchar();
while (isdigit(c)) {
x = (x<<1) + (x<<3) + c -'0';
c = getchar();
}
if (!w) x = -x;
}
template <typename T>
void Write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)Write(x / 10);
putchar(x % 10 + '0');
}
//----------------------------------------------
const int N = 500010;
const double eps = 1e-5;
int n, l, r;
int dp[N] = {0}, h[N];
struct Node {
int l, r, pos;
Node(){}
Node(int l, int r, int pos):l(l), r(r), pos(pos){}
}p[N];
double cal(int a, int b) { // 一定注意顺序 是统计 a覆盖b的最小高度
return (double)h[b] + sqrt(abs(a - b)) - (double)h[a];
}
int find(Node t, int x) {
int l = t.l, r = t.r, ans = 0;
while (l <= r) {
int mid = (l + r) >> 1;
if(cal(mid, t.pos) <= cal(mid, x)) r = mid - 1, ans = mid;
else l = mid + 1;
}
return ans;
}
void solve(bool typ) {
int l = 1, r = 0;
for_up(i, 1, n) {
if (l <= r && ++p[l].l > p[l].r) ++l;
if (l > r || cal(n, i) > cal(n, p[r].pos)) {
// p[r] 无论如何不会比i优 直接弹掉
while (l <= r && cal(p[r].l, p[r].pos) < cal(p[r].l, i)) --r;
int now = (l > r) ? i : find(p[r], i);
if (l <= r) p[r].r = now - 1;// 如果上一个区间存在 更新右端点
p[++r] = (Node){now, n, i};
}
int id = typ ? n - i + 1 : i;
dp[id] = max(dp[id], (int)ceil(cal(i, p[l].pos)));
}
}
int main() {
Read(n);
for_up(i, 1, n) Read(h[i]);
solve(0);
reverse(h + 1, h + n + 1);
solve(1);
for_up(i, 1, n) {
Write(dp[i]);
putchar('\n');
}
return 0;
}
BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】的更多相关文章
- P3515 [POI2011]Lightning Conductor[决策单调性优化]
给定一序列,求对于每一个$a_i$的最小非负整数$p_i$,使得$\forall j \neq i $有$ p_i>=a_j-a_i+ \sqrt{|i-j|}$. 绝对值很烦 ,先分左右情况单 ...
- 【BZOJ2216】[Poi2011]Lightning Conductor 决策单调性
[BZOJ2216][Poi2011]Lightning Conductor Description 已知一个长度为n的序列a1,a2,...,an.对于每个1<=i<=n,找到最小的非负 ...
- LOJ2074/2157 JSOI2016/POI2011 Lightning Conductor 决策单调性DP
传送门 我们相当于要求出\(f_i = \max\limits_{j=1}^{n} (a_j + \sqrt{|i-j|})\).这个绝对值太烦人了,考虑对于\(i>j\)和\(i<j\) ...
- Lightning Conductor 洛谷P3515 决策单调性优化DP
遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...
- 决策单调性优化dp 专题练习
决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...
- CF868F Yet Another Minimization Problem 分治决策单调性优化DP
题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...
- 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)
传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...
- [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)
第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...
- BZOJ_2216_[Poi2011]Lightning Conductor_决策单调性
BZOJ_2216_[Poi2011]Lightning Conductor_决策单调性 Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n, ...
随机推荐
- RabbitMQ 的路由模式 Topic模式
模型 生产者 package cn.wh; import java.io.IOException; import java.util.concurrent.TimeoutException; impo ...
- vector的坑——C++primer练习6.33总结
说来惭愧,一道简单的对vector递归的题目写了一个多小时,最后还是请教了大神才改出来. 首先贴上原代码: void return_vector(vector<int>::iterator ...
- thinkphp3.2.3 + nginx 配置二级域名
使用的是阿里云centOS.74 第一步: 配置urlpath server { listen ; server_name www.xxxx.com xxxx.com; root /data/www/ ...
- IdentityServer4在Asp.Net Core中的应用(一)
IdentityServer4是一套身份授权以及访问控制的解决方案,专注于帮助使用.Net 技术的公司为现代应用程序建立标识和访问控制解决方案,包括单点登录.身份管理.授权和API安全. 下面我将具体 ...
- 场景设计以及Manual Scenario和Goal-OrientedScenario的区别
Manual Scenario 手工场景 主要是设计用户变化,通过手工场景可以帮助我们分析系统的性能瓶颈.手动方案:如果要生成手动方案,请选择此方法.通过创建组并指定脚本.负载生成器和每组中包括的 V ...
- EFCore
Nuget引用 LinqKit.Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.SqlServer 然后新建类继承DbConte ...
- web常见问题排查
原帖地址:http://mp.weixin.qq.com/s?__biz=MjM5NzUwNDA5MA==&mid=200596752&idx=1&sn=37ecae802f3 ...
- Android Kotlin —— 语言结合
2017 Google I/O 大会开始就宣布,将Kotlin语言作为安卓开发的一级编程语言. Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发. Ko ...
- UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)
题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议.参会骑士至少有3个且有奇数个. 题目分析:在可以相邻的骑士之间连一条无向 ...
- 极小极大搜索 的个人理解(alpha-beta剪枝)
极小极大搜索的算法过程: 参考文档:http://www.xqbase.com/computer/search_minimax.htm (经典) 主要思想比较简单,但说清楚也不大容易.其核心思想是通过 ...