[ZJOI2010] 基站选址(线段树优化dp)

problem

luogu-P2605

solution

首先,肯定都能想到最暴力的 dpdpdp

dpi,j:idp_{i,j}:idpi,j:i 个村庄为止一共选了 jjj 个基站,且第 iii 个村庄一定建立基站的最小费用。

通过我们的定义可知第 nnn 个村庄一定被选,实际上未必。

所以我们可以建立第 n+1n+1n+1 个虚拟村庄,并要求改为建立 m+1m+1m+1 个基站。

设置信息:建立花费 c=0c=0c=0,赔偿花费 w=∞w=\inftyw=,距离 d=∞d=\inftyd=。这样就不会被其余村庄覆盖到也不会产生新花费而且一定建设。

边界我们设计好了,就看状态转移方程。

dpi,j=ci+min⁡{dpk,j−1+pay(k,i)}k<idp_{i,j}=c_i+\min\Big\{dp_{k,j-1}+pay(k,i)\Big\}\quad k<idpi,j=ci+min{dpk,j1+pay(k,i)}k<i

注意到第二维 jjj 是可以滚动的,所以本质上是一维的 dpdpdp 转移 dpi=ci+min⁡k<i{dpk+pay(k,i)}dp_{i}=c_i+\min_{k<i}\Big\{dp_{k}+pay(k,i)\Big\}dpi=ci+mink<i{dpk+pay(k,i)}

pay(k,i):pay(k,i):pay(k,i): 相邻两个基站选址在 kkkiii 村庄,这中间未被覆盖到的村庄一共支付的补偿费。

这其实很好计算。

因为距离 ddd 是递增的,我们完全可以用 lower_bound() 找到每个村庄能被覆盖到的最远左右村庄。不妨记为 sti/edist_i/ed_isti/edi

[sti,edi][st_i,ed_i][sti,edi] 中有一个村庄建立了基站,那么 iii 村庄就可以被覆盖到,不需要支付补偿费。

通常遇到这种区间产生花费的,我们会选择前缀和优化,然后分离 i,ki,ki,k 各自的贡献,把只有 kkk 产生的贡献揉成一坨扔到线段树上,最小值查询,但自己想想这里的区间与通常情况的是不一样的。

通常情况的表述应为**“能覆盖 sis_isi 范围内的所有基站”,而不是此题的“被覆盖”**。

这里我们转化一下。

再看一遍一维 dpdpdp 的转移,这次从 dpkdp_kdpk 这里入手。

唯一给的限制是 k<ik<ik<i,所以 kkk 的取值是一段区间。

不难想到用线段树维护,把 dpkdp_kdpk 当成节点权值,然后查询区间最小值。

如果我们线段树查出来的 k<stxk<st_xk<stx,那么就需要支付 wxw_xwx

而我们顺次考虑到村庄 i,stx≤i≤edxi,st_x\le i\le ed_xi,stxiedx 的时候,因为 iii 必建设基站,所以 xxx 村庄就会被覆盖。

于是我们想到将这样的 xxx 村庄挂到 edxed_xedx 上面去,可能多个 edxed_xedx 相同,用前向星/vector\text{vector}vector 存即可。

iii 考虑到 edxed_xedx,考虑完后,i←edx+1i\leftarrow ed_x+1iedx+1,我们就要给线段树上 [1,stx)[1,st_x)[1,stx) 这些村庄加上 wxw_xwx 的花费。

就是个线段树区间加操作。

答案就是每一轮的 dpn+1dp_{n+1}dpn+1 取最小值。

就没了。时间复杂度,O(nmlog⁡n)O(nm\log n)O(nmlogn),因为每个 xxx 只会挂在一个村庄下,遍历到某个村庄就把挂着的所有 xxx 的贡献一股脑往线段树上加,均摊下来是 O(1)O(1)O(1) 的。

注意: 最开始的,只建设一个基站的情况要特殊初始化 dpdpdp,后面才能以 j−1j-1j1 个基站的 dpidp_idpi 建树。

code

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define int long long
#define maxn 20005
int n, k;
int d[maxn], c[maxn], s[maxn], w[maxn], st[maxn], ed[maxn], dp[maxn];
vector < int > G[maxn];namespace SGT {#define lson now << 1#define rson now << 1 | 1#define mid (l + r >> 1)struct node { int tag, val; }t[maxn << 2];void pushdown( int now ) {if( ! t[now].tag ) return;t[lson].tag += t[now].tag;t[lson].val += t[now].tag;t[rson].tag += t[now].tag;t[rson].val += t[now].tag;t[now].tag = 0;}void build( int now, int l, int r ) {t[now].tag = 0;if( l == r ) { t[now].val = dp[l]; return; }build( lson, l, mid );build( rson, mid + 1, r );t[now].val = min( t[lson].val, t[rson].val );}void modify( int now, int l, int r, int L, int R, int v ) {if( R < l or r < L ) return;if( L <= l and r <= R ) { t[now].val += v, t[now].tag += v; return; }pushdown( now );modify( lson, l, mid, L, R, v );modify( rson, mid + 1, r, L, R, v );t[now].val = min( t[lson].val, t[rson].val );}int query( int now, int l, int r, int L, int R ) {if( r < L or R < l ) return inf;if( L <= l and r <= R ) return t[now].val;pushdown( now );return min( query( lson, l, mid, L, R ), query( rson, mid + 1, r, L, R ) );}
}signed main() {scanf( "%lld %lld", &n, &k );for( int i = 2;i <= n;i ++ ) scanf( "%lld", &d[i] );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &c[i] );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &s[i] );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &w[i] );++ n, ++ k, w[n] = d[n] = inf;for( int i = 1;i <= n;i ++ ) {ed[i] = upper_bound( d + 1, d + n + 1, d[i] + s[i] ) - d - 1;st[i] = lower_bound( d + 1, d + n + 1, d[i] - s[i] ) - d;G[ed[i]].push_back( i );}for( int i = 1, now = 0;i <= n;i ++ ) {dp[i] = now + c[i];for( int j : G[i] ) now += w[j];}int ans = dp[n];for( int j = 2;j <= k;j ++ ) {SGT :: build( 1, 1, n );for( int i = 1;i <= n;i ++ ) {dp[i] = c[i] + SGT :: query( 1, 1, n, 1, i - 1 );for( int p : G[i] ) SGT :: modify( 1, 1, n, 1, st[p] - 1, w[p] );}ans = min( ans, dp[n] );}printf( "%lld\n", ans );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cf1553E. Permutation Shift

cf1553E. Permutation Shift 题意&#xff1a; 给出一个1到n的排列&#xff0c;每次可以交换两个数&#xff0c;问在交换最多m次(m < n/3)之后能不能得到由1 2 3 … n循环右移所得到的的排列&#xff0c;输出所有能得到的排列和循环右移的次数。 数据范围&#xff1a;n &l…

结合使用 Draft 与 Tencent Kubernetes Engine (TKE)

Draft 是一种开源工具&#xff0c;有助于在 Kubernetes 群集中打包和部署应用程序容器&#xff0c;让你专注于开发周期 - 专注开发的“内部循环”。 在开发代码期间&#xff0c;但尚未将代码提交到版本控制之前&#xff0c;Draft 将会运行。 借助 Draft&#xff0c;可在代码发生…

[ZJOI2010] 贪吃的老鼠(二分+差分+神仙建图网络流)

problem luogu-P2570 solution 卧槽网络流尼玛神题 首先这个最小延长时间 TTT &#xff0c;套路地考虑二分&#xff0c;将问题转化为判定性问题。 其次 n,mn,mn,m 和奶酪存在时间 [l,r][l,r][l,r] 的量级差很大&#xff0c;我们肯定会猜想一段时间内选择吃奶酪的老鼠是一样…

cf1553D. Backspace

cf1553D. Backspace 题意&#xff1a; 有一个字符串A,现在将其一个一个输入至B中,在输入一个字符时,如果按下backspace,那么这个字符不会被键入,而且如果B不为空,则前一位(B.back)也会被删除,现给出一个字符串C,问能否得到一个B&#xff0c;使得BC 题解&#xff1a; 为了通…

基于IdentityServer的系统对接微信公众号

业务需求公司有两个业务系统&#xff0c;A和B&#xff0c;AB用户之间属于多对一的关系&#xff0c;数据库里面也就是两张表&#xff0c;A表有个外键指向B。现在需要实现以下几个功能。A用户扫描B的二维码&#xff0c;填写相关的注册信息&#xff0c;注册完成之后自动属于B。也就…

[TJOI2012] 旅游(树的直径)

problem 写的什么jb题意&#xff01;这个语文水平。。。。 洛谷的一堆题解看下来也没懂他们懂得题目大意&#xff0c;真是给我蚌埠住了 luogu评测链接 一句话题意&#xff1a;给定一个三角剖分&#xff0c;求任意两顶点穿过的最多三角形个数&#xff08;只经过某三角形顶点…

Python知识(4/20):Python条件判断

任何一个复杂的系统都是由三种基本结构组成&#xff1a;顺序结构、分支结构、循环结构。其中 顺序结构最简单&#xff0c;程序从上到下依次执行&#xff0c;就如同生活中一条笔直的大马路&#xff0c;一路畅行无阻&#xff1b; 分支结构是指当程序执行到某步时&#xff0c;需根…

Ocelot Api网关教程(9)- QoS

本文介绍Ocelot中的QoS(Quality of Service)&#xff0c;其使用了Polly对超时等请求下游失败等情况进行熔断。1、添加Nuget包添加 Ocelot.Provider.Polly 到OcelotGetway项目中2、修改 Startup.ConfigureServices 如下来添加Polly&#xff1a;services .AddOcelot(new Confi…

cf1553F. Pairwise Modulo

cf1553F. Pairwise Modulo 题意&#xff1a; 给你一个数组a&#xff0c;a由n个不同的数组成,让你求出对应的数组p 数组p的定义为&#xff1a; pk∑1≤i,j≤kaimodajp_{k}\sum_{1\leq i,j\leq k}a_{i} \mod a_{j}pk​∑1≤i,j≤k​ai​modaj​ 题解&#xff1a; 官方题解 首…

[ZJOI2011]营救皮卡丘(费用流 + 最短路)

problem luogu-P4542 solution 刚开始就直观感觉 dpdpdp 不动&#xff0c;却有个看似“理所当然”的贪心&#xff1a;每次跑 kkk 个人所在点到扩展据点的最短距离&#xff0c;然后让最近的人去破环那个据点。 啪啪敲完后小样例&#xff08;实在太水&#xff09;就过了&…

Deltix Round, Spring 2021 (open for everyone, rated, Div. 1 + Div. 2)

Deltix Round, Spring 2021 (open for everyone, rated, Div. 1 Div. 2) 题号题目知识点AGame of LifeBLord of the ValuesCCompression and ExpansionDLove-HateECrypto LightsFFavorite GameGTry BookingHHopping Around the Array

Abp框架准备加入.NET Foundation

Abp团队正准备尝试将Abp项目加入.NET Foundation!既然申请了,必然有很大的自信能够成功,请大家等待好消息!Abp中文网会第一时间跟进.点击阅读原文查看最新进展.

[ZJOI2011] 道馆之战(树链剖分)

problem luogu-P4679 理解清楚题意又是一个世纪的更迭了 给定一个树&#xff0c;每个节点位置上实际放了两个节点。 然后若干次修改和查询。... 能走&#xff0c;#\## 不能走。 询问 u→vu\rightarrow vu→v 的简单路径上最长能走的距离。&#xff08;是强制从 uuu 开始&a…

[NOI2008] 志愿者招募(线性规划-对偶问题-费用流)

problem luogu-P3980 solution 志愿者连续工作 [si,ti][s_i,t_i][si​,ti​] 天&#xff0c;我们可以提炼出网络流二十四题中《最长k可重区间集问题》的模型。 同样地&#xff0c;把 1∼n1\sim n1∼n 天抽象成一条 1∼n11\sim n11∼n1 个点的链条。 源点 s→1s\rightarrow…

互达的集合(线段树)

problem 给定数组 l,rl,rl,r。求有多少个非空集合 SSS&#xff0c;满足 ∀i,j∈Sli≤j≤ri\forall_{i,j\in S}\ l_i\le j\le r_i∀i,j∈S​ li​≤j≤ri​。 集合内对于任意一个点而言&#xff0c;其余点均能被自己的范围覆盖到。 n≤2e5n\le 2e5n≤2e5。 solution 分享一下…

【学习笔记】线性规划与对偶问题和LP对偶费用流([ZJOI2013]防守战线题解)

线性规划与对偶问题 原问题&#xff1a; min⁡{7x1x25x3}s.t.{x1−x23x3≥105x12x2−x3≥6xi≥0\min\{7x_1x_25x_3\} \\ s.t.\begin{cases} x_1-x_23x_3\ge 10\\ 5x_12x_2-x_3\ge 6\\ x_i\ge 0\end{cases} min{7x1​x2​5x3​}s.t.⎩⎪⎨⎪⎧​x1​−x2​3x3​≥105x1​2x2​−…

【学习笔记】DAG / 一般有向图的支配树 / 灭绝树

定义与声明 一个有向图 GGG。给定一个起点 sss&#xff0c;假设 sss 能到达所有点。 若去掉某个点 iii 后&#xff0c;sss 无法到达 jjj&#xff0c;则称 iii 为 jjj 的支配点。 显然支配点存在传递关系。 以 sss 为根&#xff0c;使得对于任意节点 iii&#xff0c;其树上祖…

[ZJOI2014] 星系调查(树上差分 + 数学推式子)

problem luogu-P3340 题面写得那么长&#xff0c;其实说白了就是求一条直线&#xff0c;使得若干个点到这条直线的距离平方的和最小&#xff0c;求这个最小值。 solution 我超爱数学&#xff0c;数学就是我的命&#xff0c;我一天不学数学我就难受&#xff01; 假设拟合出…

[ZJOI2014] 璀璨光华(bfs建图 + dfs搜索)

problem luogu-P3342 solution 你感觉这道题没考什么&#xff0c;又感觉考了什么 通过样例以及题面&#xff0c;我们并未获取到『立方体每个小方块的编号是按一定规则命名』的信息。 也就是说&#xff0c;我们需要通过输入的每个小方块相邻的编号的信息来建出这个立方体的…

cf1523A. Game of Life

cf1523A. Game of Life 题意&#xff1a; 包含n个元素的数组&#xff0c;数值为1或0&#xff0c;如果一个元素为0&#xff0c;并且其周围正好只有一个为1的元素&#xff0c;那么下一刻本元素也会变成1. 给你一个数值&#xff0c;问你m次时刻后数组的状态 题解&#xff1a; …