BZOJ3437 小P的牧场 动态规划 斜率优化
原文链接http://www.cnblogs.com/zhouzhendong/p/8696321.html
题目传送门 - BZOJ3437
题意
给定两个序列$a,b$,现在划分$a$序列。
被划分出来的段$[j,i]$的花费为$a_i+\sum_{k=j+1}^{i}(i-k)b_k$。
一种划分方式的花费就是每一段的花费之和。
问最小花费。
序列长度$\leq 10^6$。
题解
首先我们不难写出DP方程:
$$dp_i=max\{dp_j+\sum_{k=j+1}^{i}(i-k)b_k\}+a_i\ \ \ \ \ (0\leq j<i)$$
然后容易看出可以斜率优化。
然后搬出斜率优化的套路。
先化简些式子。
$$dp_j+\sum_{k=j+1}^{i}(i-k)b_k\\=dp[j]-\sum_{k=j+1}^{i}kb_k+i\sum_{k=j+1}^{i}b_k$$
设:
$$sum_i=\sum_{j=1}^{i}b_j$$
$$vsum_i=\sum_{j=1}^{i}b_j\times j$$
则原式=
$$dp_j-vsum_i+vsum_j+isum_i-isum_j$$
然后开始斜率优化DP的套路部分:
设
$$x_i=sum_i$$
$$y_i=dp_i+vsum_i$$
则原式=
$$y_j-vsum_i+isum_i-ix_j$$
假设$j>k$且从$j$转移不劣于$k$,则:
$$y_j-vsum_i+isum_i-ix_j\leq y_k-vsum_i+isum_i-ix_k$$
化简得:
$$\frac{y_j-y_k}{x_j-x_k}\leq i$$
然后献上斜率优化DP套路:
注意由于开始限制了$j>k$所以$x_j-x_k>0$,所以最后两边同时相除不等式仍然成立。
设
$$g_{i,j}=\frac{y_i-y_j}{x_i-x_j}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (i>j)$$
则上式可以表示为$g_{j,k}<i$
我们来发掘以下$g_{j,k}$的性质。
1. 当$g_{j,k}\leq i$时,由于随着$i$变大,$i$也变大,所以显然从$k$转移是永远不会比$j$好的,所以我们可以把$k$扔掉。
2. 当$g_{i,j}\leq g_{j,k}$时,从$i$或者$k$转移至少有一个不比$j$差,所以可以把$j$扔掉。为什么??
若$g_{i,j}\leq i$,显然$j$要被扔掉,根据第一个性质。
若$g_{i,j}>i$,则$g_{j,k}>i$,那么显然$j$比$k$差,也得被扔掉。
于是我们可以用一个单调队列来维护斜率的单调性。
具体的:
当情况1发生的时候让队首出队。
在进队的时候,如果发生情况2,那么先让队尾出队,然后再进队。
为了避免精度问题,我们可以把$x_i-x_j$乘上来。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1000005;
int n,q[N],head=1,tail=0;
LL a[N],b[N],sum[N],vsum[N],dp[N],x[N],y[N];
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for (int i=1;i<=n;i++){
scanf("%lld",&b[i]);
sum[i]=sum[i-1]+b[i];
vsum[i]=vsum[i-1]+b[i]*i;
}
q[++tail]=0;
for (int i=1;i<=n;i++){
int j=q[head+1],k=q[head];
while (tail-head>0&&y[j]-y[k]<=(x[j]-x[k])*i)
head++,j=q[head+1],k=q[head];
j=k;
dp[i]=dp[j]+vsum[j]-vsum[i]+(sum[i]-sum[j])*i+a[i];
x[i]=sum[i];
y[i]=dp[i]+vsum[i];
j=q[tail],k=q[tail-1];
while (tail-head>0&&(y[i]-y[j])*(x[j]-x[k])<=(y[j]-y[k])*(x[i]-x[j]))
tail--,j=q[tail],k=q[tail-1];
q[++tail]=i;
}
printf("%lld",dp[n]);
return 0;
}
BZOJ3437 小P的牧场 动态规划 斜率优化的更多相关文章
- bzoj3437 小P的牧场(斜率优化dp)
3437: 小P的牧场 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2025 Solved: 1110[Submit][Status][Discu ...
- BZOJ3437 小P的牧场 【斜率优化dp】
3437: 小P的牧场 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1502 Solved: 836 [Submit][Status][Disc ...
- 【BZOJ-3437】小P的牧场 DP + 斜率优化
3437: 小P的牧场 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 705 Solved: 404[Submit][Status][Discuss ...
- BZOJ 3437 小P的牧场(斜率优化DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3437 [题目大意] n个牧场排成一行,需要在某些牧场上面建立控制站, 每个牧场上只能建 ...
- bzoj 3437: 小P的牧场【斜率优化】
emmm妹想到要倒着推 先假设只在n建一个控制站,这样的费用是\( \sum_{i=1}^{n} b[i]*(n-i) \)的 然后设f[i]为在i到n键控制站,并且i一定建一个,能最多节省下的费用, ...
- bzoj3437小P的牧场
bzoj3437小P的牧场 题意: n个牧场,在每个牧场见控制站的花费为ai,在该处建控制站能控制从此处到左边第一个控制站(或边界)之间的牧场.一个牧场被控制的花费等于它到控制它的控制站之间的牧场数目 ...
- 【学习笔记】动态规划—斜率优化DP(超详细)
[学习笔记]动态规划-斜率优化DP(超详细) [前言] 第一次写这么长的文章. 写完后感觉对斜优的理解又加深了一些. 斜优通常与决策单调性同时出现.可以说决策单调性是斜率优化的前提. 斜率优化 \(D ...
- bzoj3437小P的牧场 斜率优化dp
3437: 小P的牧场 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1542 Solved: 849[Submit][Status][Discus ...
- BZOJ3437:小P的牧场(斜率优化DP)
Description 小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站,每个牧场上只能建立一个控制站,每个控制 ...
随机推荐
- word发布博客
无向图双连通部件(双连通分量) 关节点和桥边的定义: 双连通部件的性质 每一个双连通部件应该包含至少两个顶点,除非整个无向图只包含一个顶点 如果两个双连通部件包含同一个顶点,那么这个共有的顶点 ...
- C# web Api ajax发送json对象到action中
直接上代码: 1.Product实体
- css一些基础效果
1.旋转 .center>.bj>.div1>ul>li>.img1:hover {transform: rotate(-360deg);transition: 1s}/ ...
- Confluence 6 针对你的数据库类型确定校验 SQL
不同的数据库通常要求不同的 SQL 校验查询.校验查询通常需要尽可能的简单,这个查询在链接从数据库连接池中取出的时候都会被执行一次. 针对不同的数据库类型,我们推荐先的校验查询 SQL: MySQL ...
- Confluence 6 当前使用的数据库状态
进入 > 基本配置(General Configuration) > 问题检查和支持工具(Troubleshooting and support tools) 你就可以看到当前使用的数据 ...
- SELinux简介(转载)
几乎可以肯定每个人都听说过 SELinux (更准确的说,尝试关闭过),甚至某些过往的经验让您对 SELinux 产生了偏见.不过随着日益增长的 0-day 安全漏洞,或许现在是时候去了解下这个在 L ...
- kafka消息存储与partition副本原理
消息的存储原理: 消息的文件存储机制: 前面我们知道了一个 topic 的多个 partition 在物理磁盘上的保存路径,那么我们再来分析日志的存储方式.通过 ll /tmp/kafka-logs/ ...
- 小学生都看得懂的C语言入门(4): 数组与函数
// 之前判断素数, 只需要到sqrt(x)即可,//更加简单的, 判断能够比已知的小于x的素数整除, 运行更快 #include <stdio.h> // 之前判断素数, 只需要到sqr ...
- php模拟数据请求
php:模拟后台接受数据的步骤<?php> 1.连接数据库 $host="localhost"; $uname="root"; $upwd=&quo ...
- delete web server(nginx)
#!/bin/bash conf_dir1="/usr/local/nginx/conf/vhost.d" #conf_dir2="/usr/local/apache2/ ...