题目大意:略 洛谷题面传送门 BZOJ题面传送门

注意题目的描述,是村庄在一个范围内去覆盖基站,而不是基站覆盖村庄,别理解错了

定义$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)的更多相关文章

  1. 洛谷$P2605\ [ZJOI2010]$基站选址 线段树优化$dp$

    正解:线段树优化$dp$ 解题报告: 传送门$QwQ$ 难受阿,,,本来想做考试题的,我还造了个精妙无比的题面,然后今天讲$dp$的时候被讲到了$kk$ 先考虑暴力$dp$?就设$f_{i,j}$表示 ...

  2. [ZJOI2010]基站选址,线段树优化DP

    G. base 基站选址 内存限制:128 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较   题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离 ...

  3. luogu P2605 [ZJOI2010]基站选址 线段树优化dp

    LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cd ...

  4. 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中间的不能被满足的村庄的赔偿金之 ...

  5. BZOJ1835: [ZJOI2010]base 基站选址(线段树优化Dp)

    Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...

  6. bzoj 1835: [ZJOI2010]基站选址

    Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...

  7. 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 ...

  8. BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】

    BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...

  9. [AGC011F] Train Service Planning [线段树优化dp+思维]

    思路 模意义 这题真tm有意思 我上下楼梯了半天做出来的qwq 首先,考虑到每K分钟有一辆车,那么可以把所有的操作都放到模$K$意义下进行 这时,我们只需要考虑两边的两辆车就好了. 定义一些称呼: 上 ...

随机推荐

  1. 韩国 DBA 博客

    http://mysqldba.tistory.com/ http://cafe.naver.com/mysqlpg http://cafe.naver.com/realmysql http://wi ...

  2. bzoj-3524 Couriers

    题意: 给出一个长度为n的序列和m次询问. 每次询问给出区间[l,r],求区间中出现次数大于(r-l+1)/2的数字. n.m<=500000.1<=每一个数字<=n: 题解: 主席 ...

  3. zoj3886--Nico Number(素数筛+线段树)

    Nico Number Time Limit: 2 Seconds      Memory Limit: 262144 KB Kousaka Honoka and Minami Kotori are ...

  4. yolo源码解析(3):进行简单跳帧

    视频检测命令  ./darknet detector demo cfg/coco.data cfg/yolov3-tiny.cfg yolov3-tiny.weights ../../dataset/ ...

  5. C语言 - typedef struct 与struct

    c语言中可以选择的数据类型太少了. Java中有一些高级的数据结构. 结构中能够存放基本的数据类型以及其他的结构. 结构定义,一般放在程序的开头部分. 一般放在include之后. #include ...

  6. DDos攻击的一些领域知识——(流量模型针对稳定业务比较有效)不稳定业务采用流量成本的检测算法,攻击发生的时候网络中各个协议的占比发生了明显的变化

    在过去,很多防火墙对于DDoS攻击的检测一般是基于一个预先设定的流量阈值,超过一定的阈值,则会产生告警事件,做的细一些的可能会针对不同的流量特征设置不同的告警曲线,这样当某种攻击突然出现的时候,比如S ...

  7. hdoj--3488--Tour(KM)

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submi ...

  8. poj1700--贪心--Crossing River

    Crossing River Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12260   Accepted: 4641 D ...

  9. AIX&nbsp;常用命令汇总(一)

    命令 内核 如何知道自己在运行 32 位内核还是 64 位内核? 要显示内核启用的是 32 位还是 64 位,可输入以下命令: bootinfo -K 如何知道自己在运行单处理器还是多处理器内核? / ...

  10. python 飞机大战 实例

    飞机大战 #coding=utf-8 import pygame from pygame.locals import * import time import random class Base(ob ...