BZOJ 1835 [ZJOI2010]基站选址 (线段树优化DP)
注意题目的描述,是村庄在一个范围内去覆盖基站,而不是基站覆盖村庄,别理解错了
定义$f[i][k]$表示只考虑前i个村庄,一共建了$k$个基站,最后一个基站建在了i处,最小的总花费
$f[i][k]=min(f[j][k]+calc(j,i))\;calc(j,i)$表示$i$和$j$之间,无法被覆盖的点,需要付的补偿总和
考虑如何求出$calc(j,i)$
定义$st_{i}$,$ed_{i}$表示第$i$个村庄能覆盖的最左端点和最右端点
即$st_{i}$到$ed_{i}$之间只要有一个村庄有基站,那么村庄i就不需要被补偿
可以用二分查找实现
把相同$ed_{i}$的村庄编号记录在$ed_{i}$这个位置
$DP$时,我们从左往右遍历要建基站的位置$x$,如果有一个村庄$i$的$ed_{i}<$当前位置$x$,那么如果$x$的决策如果选在了$[1,st_{i}-1]$,即上一个基站建在了$[1,st_{i}-1]$,那么村庄$i$需要被补偿,区间修改,用线段树实现
而转移就是查询区间最小值,同样用线段树实现即可
细节略多
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 20010
#define K1 105
#define ll long long
#define dd double
#define inf 0x3f3f3f3f3f3f3f3fll
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
} struct SEG{
ll mi[N1<<],tag[N1<<];
inline void pushup(int rt){ mi[rt]=min(mi[rt<<],mi[rt<<|]); }
inline void pushdown(int rt)
{
if(!tag[rt]) return;
mi[rt<<]+=tag[rt]; mi[rt<<|]+=tag[rt];
tag[rt<<]+=tag[rt]; tag[rt<<|]+=tag[rt];
tag[rt]=;
}
void build(ll *f,int l,int r,int rt)
{
tag[rt]=;
if(l==r){ mi[rt]=f[l]; return; }
int mid=(l+r)>>;
build(f,l,mid,rt<<);
build(f,mid+,r,rt<<|);
pushup(rt);
}
void update(int L,int R,int l,int r,int rt,ll w)
{
if(L<=l&&r<=R){ mi[rt]+=w; tag[rt]+=w; return; }
int mid=(l+r)>>; pushdown(rt);
if(L<=mid) update(L,R,l,mid,rt<<,w);
if(R>mid) update(L,R,mid+,r,rt<<|,w);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return mi[rt];
int mid=(l+r)>>; ll ans=inf; pushdown(rt);
if(L<=mid) ans=min(ans,query(L,R,l,mid,rt<<));
if(R>mid) ans=min(ans,query(L,R,mid+,r,rt<<|));
return ans;
}
}s; vector<int>id[N1];
int n,K;
int d[N1],c[N1],p[N1],w[N1],st[N1],ed[N1];
ll f[N1]; int main()
{
scanf("%d%d",&n,&K);
int i,j,k,l,r,x,mid; ll ans=inf;
for(i=;i<=n;i++) d[i]=gint();
for(i=;i<=n;i++) c[i]=gint();
for(i=;i<=n;i++) p[i]=gint();
for(i=;i<=n;i++) w[i]=gint();
for(i=;i<=n;i++)
{
l=,r=i,st[i]=i;
while(l<=r)
{
mid=(l+r)>>;
if(d[mid]>=d[i]-p[i]) st[i]=mid,r=mid-;
else l=mid+;
}
l=i,r=n,ed[i]=i;
while(l<=r)
{
mid=(l+r)>>;
if(d[mid]<=d[i]+p[i]) ed[i]=mid,l=mid+;
else r=mid-;
}
id[ed[i]].push_back(i);
}
memset(s.mi,0x3f,sizeof(s.mi));
s.update(,,,n,,-(inf));
for(k=;k<=K;k++)
{
for(i=;i<=n+;i++)
{
f[i]=s.query(,i-,,n,)+c[i];
for(j=;j<id[i].size();j++)
{
x=id[i][j];
s.update(,st[x]-,,n,,w[x]);
}
}
ans=min(ans,f[n+]);
s.build(f,,n,);
}
for(i=;i<=n;i++)
{
for(j=;j<id[i].size();j++)
{
x=id[i][j];
s.update(,st[x]-,,n,,w[x]);
}
}
ans=min(ans,s.query(,n,,n,));
printf("%lld\n",ans);
return ;
}
BZOJ 1835 [ZJOI2010]基站选址 (线段树优化DP)的更多相关文章
- 洛谷$P2605\ [ZJOI2010]$基站选址 线段树优化$dp$
正解:线段树优化$dp$ 解题报告: 传送门$QwQ$ 难受阿,,,本来想做考试题的,我还造了个精妙无比的题面,然后今天讲$dp$的时候被讲到了$kk$ 先考虑暴力$dp$?就设$f_{i,j}$表示 ...
- [ZJOI2010]基站选址,线段树优化DP
G. base 基站选址 内存限制:128 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离 ...
- luogu P2605 [ZJOI2010]基站选址 线段树优化dp
LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cd ...
- luogu2605 基站选址 (线段树优化dp)
设f[i][j]表示在第i个村庄建第j个基站的花费 那么有$f[i][j]=min\{f[k][j-1]+w[k,i]\}$,其中w[k,i]表示在k,i建基站,k,i中间的不能被满足的村庄的赔偿金之 ...
- BZOJ1835: [ZJOI2010]base 基站选址(线段树优化Dp)
Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...
- bzoj 1835: [ZJOI2010]基站选址
Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...
- Codeforces Round #426 (Div. 2) D 线段树优化dp
D. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...
- BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】
BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...
- [AGC011F] Train Service Planning [线段树优化dp+思维]
思路 模意义 这题真tm有意思 我上下楼梯了半天做出来的qwq 首先,考虑到每K分钟有一辆车,那么可以把所有的操作都放到模$K$意义下进行 这时,我们只需要考虑两边的两辆车就好了. 定义一些称呼: 上 ...
随机推荐
- 【ACM】nyoj_7_街区最短路径问题_201308051737
街区最短路径问题时间限制:3000 ms | 内存限制:65535 KB 难度:4描述 一个街区有很多住户,街区的街道只能为东西.南北两种方向. 住户只可以沿着街道行走. 各个街道之间的间隔相等. ...
- php模拟并发
原文: http://blog.csdn.net/zhang_xinglong/article/details/16339867 ----------------------------------- ...
- Java中的事务
Java中的事务 学习了:https://www.cnblogs.com/chengpeng15/p/5802930.html 膜拜一下 org 分为三类:jdbc事务.jta事务.容器事务:
- php学习之道:WSDL具体解释(一)
WSDL文档使用web服务描写叙述语言来定义服务. 文档包含逻辑(抽象)部分和详细部分. 抽象部分用于定义独立于实现的数据类型和消息,详细部分定义一个endpoint怎样实现一个能够与外界进行交互的服 ...
- 根据图片url地址获取图片的宽高
/** * 根据img获取图片的宽高 * @param img 图片地址 * @return 图片的对象,对象中图片的真实宽高 */ public BufferedImage getBufferedI ...
- 高可用技术工具包 High Availability Toolkit
HighAvailabilityToolkit High Availability Toolkit includes several solutions by which achieving arch ...
- Intel Media SDK安装步骤
!!!(gcc/g++版本要在4.8以上,本人使用的是5.4版本) 要先安装依赖,按以下步骤依次执行 1.LIBVA git clone https://github.com/intel/libva. ...
- Windows下搭建ffmpeg+VS2008开发环境详细教程【转】
本文转载自:http://www.voidcn.com/article/p-vxdntdgc-bkq.html 由于个人是从事音视频开发相关的工作,所以也把自己的一些过程写下来,方便大家以及自己查看, ...
- spark rdd median 中位数求解
lookup(key) Return the list of values in the RDD for key key. This operation is done efficiently if ...
- hdoj--3072--Intelligence System(scc+缩点+数据去重)
Intelligence System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...