正解:线段树优化$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. 修改Mariadb存储路径

    大部分基于此文章操作:http://lddyw.blog.51cto.com/4151746/1684364 找个好久的资料,都打算源码安装了,最后终于更改成功了. 环境:CentOS6.6 64位虚 ...

  2. oracle函数 ASCII(x1)

    [功能]:返回字符表达式最左端字符的ASCII 码值. [参数]:x1,字符表达式 [返回]:数值型 [示例] SQL> select ascii('A') A,ascii('a') a,asc ...

  3. windows 和 linux 安装 tensorflow

    安装 跟往常一样,我们用 Conda 来安装 TensorFlow.你也许已经有了一个 TensorFlow 环境,但要确保你安装了所有必要的包. OS X 或 Linux 运行下列命令来配置开发环境 ...

  4. C运行时库函数

    C运行时库函数是指C语言本省支持的一些基本函数,通常是汇编直接实现的. API函数是操作系统提供给用户方便设计应用程序的函数,实现一些特定的功能,API函数也是C语言的函数实现的. 他们之间区别是: ...

  5. 解决bootStrap selectpicker 下拉栏上方弹出

    最近项目中遇到了一个使用bootStrap selectpicker 进行下拉栏展示的时候出现在元素上方弹出展示的问题,可把我难受坏了,和测试互怼最终以失败告终(人家还是一个娇滴滴的小姑娘),在查了a ...

  6. 仿IOS效果-带弹簧动画的ListView

    背景介绍 最近项目打算做一个界面,类似于dayone首页的界面效果,dayone 是一款付费应用,目前只有IOS端.作为一个资深懒惰的程序员,奉行的宗旨是绝对不重复造一个轮子.于是乎,去网上找一大堆开 ...

  7. day6_python之pickle、shelve序列化和反序列化

    pickle.shelve,python私有,支持所有python数据类型 一.pickle dic={'name':'egon','age':18} print(pickle.dumps(dic)) ...

  8. 云数据库 MySQL 8.0 重磅发布,更适合企业使用场景的RDS数据库

    点击订阅新品发布会! 新产品.新版本.新技术.新功能.价格调整,评论在下方,下期更新!关注更多内容,了解更多 最新发布 云数据库MySQL 8.0 升级发布会 2019年5月29日15时,阿里云云数据 ...

  9. H3C 无线覆盖原则-蜂窝式覆盖

  10. 运行项目npm run dev时报错: ~Error: Cannot find module 'webpack-cli/bin/config-yargs', 原因是

    webpack@3.X运行项目npm run dev时报错: ~Error: Cannot find module 'webpack-cli/bin/config-yargs' 我的原因是:  web ...