正解:线段树优化$dp$

解题报告:

传送门$QwQ$

难受阿,,,本来想做考试题的,我还造了个精妙无比的题面,然后今天讲$dp$的时候被讲到了$kk$

先考虑暴力$dp$?就设$f_{i,j}$表示选的第$j$个基站是$i$的最小费用,就有$f_{i,j}=min(f_{k,j}+cost(k,i))+c_i$,这个$cost$就$[k+1,i-1]$之间所有基站的补偿之和.

发现这个$cost$并不好求?于是逆向思考,每次在决策完选$x$转移完之后就会进入不选$x$的阶段嘛(因为是,$j$在外层循环$i$在内层,也就每次只会选一个基站,所以决策完第$j$个选$x$后就会决策第$j$个选$x$之后的基站,那第$x$个基站就不会被选了$QwQ$),那就把$[1,x]$范围内所有因为不选$x$而导致代价增加的加上

于是先预处理一个$st_{i}$和一个$ed_{i}$数组,表示能让$i$被覆盖的基站的编号范围,然后每次把所有$ed_{i}=x$的点找出来.但是发现当上一次选的点在$[st_{i},ed_{i}-1]$范围内的时候就依然没有关系,所以就只要$f_{[1,st[i]-1],j}+=w_i$

现在就变成了区间加区间查询最小值,线段树维护就好,$over$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rc register char
#define rb register bool
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
#define lb(x) lower_bound(d+1,d+1+n,x)-d const int N=+,inf=0x3f3f3f3f;
int n,K,d[N],c[N],s[N],w[N],st[N],ed[N],tr[N<<],tag[N<<],ed_cnt,head[N],f[N],as;
struct edg{int to,nxt;}edge[N]; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il void ad(ri x,ri y){edge[++ed_cnt]=(edg){x,head[y]};head[y]=ed_cnt;}
void build(ri nw,ri l,ri r)
{
tag[nw]=;if(l==r)return void(tr[nw]=f[l]);
ri mid=(l+r)>>;build(nw<<,l,mid);build(nw<<|,mid+,r);
tr[nw]=min(tr[nw<<],tr[nw<<|]);
}
il void pushdown(ri nw)
{
if(!tag[nw])return;
tag[nw<<]+=tag[nw];tag[nw<<|]+=tag[nw];tr[nw<<]+=tag[nw];tr[nw<<|]+=tag[nw];tag[nw]=;
}
void add(ri nw,ri l,ri r,ri to_l,ri to_r,ri dat)
{
if(to_l<=l && r<=to_r){tr[nw]+=dat;tag[nw]+=dat;return;}//return void(tr[nw]+=dat,tag[nw]+=dat);
pushdown(nw);ri mid=(l+r)>>;
if(mid>=to_l)add(nw<<,l,mid,to_l,to_r,dat);if(mid<to_r)add(nw<<|,mid+,r,to_l,to_r,dat);
tr[nw]=min(tr[nw<<],tr[nw<<|]);
}
int query(ri nw,ri l,ri r,ri to_l,ri to_r)
{
// printf("nw=%d l=%d r=%d to_l=%d to_r=%d\n",nw,l,r,to_l,to_r);
if(to_l<=l && r<=to_r)return tr[nw];
pushdown(nw);ri mid=(l+r)>>,ret=inf;
if(mid>=to_l)ret=query(nw<<,l,mid,to_l,to_r);if(mid<to_r)ret=min(ret,query(nw<<|,mid+,r,to_l,to_r));
// printf("[%d,%d]:%d\n")
return ret;
} int main()
{
// freopen("2605.in","r",stdin);//freopen("2605.out","w",stdout);
n=read();K=read()+;rp(i,,n)d[i]=read();rp(i,,n)c[i]=read();rp(i,,n)s[i]=read();rp(i,,n)w[i]=read();++n;d[n]=w[n]=inf;
rp(i,,n){st[i]=lb(d[i]-s[i]);ed[i]=lb(d[i]+s[i]);if(d[ed[i]]>d[i]+s[i])--ed[i];ad(i,ed[i]);}
ri ret=;rp(i,,n){f[i]=ret+c[i];e(j,i)ret+=w[t(j)];}as=f[n];
rp(i,,K)
{
build(,,n);
rp(j,,n)
{
f[j]=(j>i-?query(,,n,i-,j-):)+c[j];//printf("f[%d]=%d=%d+%d\n",j,f[j],j>i-1?query(1,1,n,1,j-1):0,c[j]);
e(k,j)if(st[t(k)]>)add(,,n,,st[t(k)]-,w[t(k)]);
}
as=min(as,f[n]);
}
printf("%d\n",as);
return ;
}

洛谷$P2605\ [ZJOI2010]$基站选址 线段树优化$dp$的更多相关文章

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

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

  2. BZOJ 1835 [ZJOI2010]基站选址 (线段树优化DP)

    题目大意:略 洛谷题面传送门 BZOJ题面传送门 注意题目的描述,是村庄在一个范围内去覆盖基站,而不是基站覆盖村庄,别理解错了 定义$f[i][k]$表示只考虑前i个村庄,一共建了$k$个基站,最后一 ...

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

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

  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. 【BZOJ1835】[ZJOI2010]base 基站选址 线段树+DP

    [BZOJ1835][ZJOI2010]base 基站选址 Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯 ...

  7. [洛谷P2605] ZJOI2016 基站选址

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

  8. P2605 [ZJOI2010]基站选址

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

  9. 洛谷 P3373 【模板】线段树 2

    洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...

随机推荐

  1. 怎么清除火狐浏览器的cookie?

    火狐浏览器清除Cookie方法/步骤 1.打开火狐浏览器.并在火狐浏览器工具栏找到并单击“工具”下的“选项”. 2.在打开的“火狐浏览器选项”程序窗口中,找到工具栏中的“隐私”并单击,在隐私选项下找到 ...

  2. 11 session 使用

    #session 使用app.secret_key = "dsada12212132dsad1232113"app.config['PERMANENT_SESSION_LIFETI ...

  3. [\s\S]*?懒惰模式特殊情形

    通常理解[\s\S]*?X (X代表任意指定字符) 表示匹配任何字符的懒惰模式,一旦遇到后面出现的X便停止匹配,但实际不是如此,会尽可能的把后面的内容也匹配进去.如: 表达式 <tr[\s\S] ...

  4. iptablesIP规则的保存与恢复

    iptables-save把规则保存到文件中,再由目录rc.d下的脚本(/etc/rc.d/init.d/iptables)自动装载 使用命令iptables-save来保存规则.一般用 iptabl ...

  5. css模仿ipad的日历

    https://www.cnblogs.com/sandraryan/ 题外话之:最近的练习用js之类的写起来会简单点,但是为了巩固基础,只好html和css硬怼页面X﹏X 这是一个日历的代码 注释有 ...

  6. C# 强转会不会抛出异常

    最近遇到一个小伙伴问我,从一个很大的数强转,会不会抛出异常.实际上不会出现异常 最简单的代码是使用一个比 maxvalue 大的数,然后用它强转 long tathkDucmmsc = int.Max ...

  7. JPA+Postgresql+Spring Data Page分页失败

    按照示例进行如下代码编写 Repository Page<DeviceEntity> findByTenantId(int tenantId, Pageable pageable); se ...

  8. HDU 6621"K-th Closest Distance"(二分+主席树)

    传送门 •题意 有 $m$ 次询问,每次询问求 $n$ 个数中, $[L,R]$ 区间距 $p$ 第 $k$ 近的数与 $p$ 差值的绝对值: •题解 二分答案,假设当前二分的答案为 $x$,那么如何 ...

  9. H3C 静态路由配置示例

  10. Can you find it?——[二分查找]

    Description Give you three sequences of numbers A, B, C, then we give you a number X. Now you need t ...