BZOJ1835 [ZJOI2010] 基站选址 【动态规划】【线段树】
题目分析:
首先想一个DP方程,令f[m][n]表示当前在前n个村庄选了m个基站,且第m个基站放在n处的最小值,转移可以枚举上一个放基站的村庄,然后计算两个村庄之间的代价。
仔细思考两个基站之间村庄的代价,会发现对于一个村庄,它需要付出代价的时候当且仅当上一个基站控制不到它,下一个基站也控制不到它,所以可以计算使它不付出代价的基站区间,然后在超过这段区间的时候加影响。具体来说就是在线段树上面加w[i]。注意滚动数组。
代码:
#include<bits/stdc++.h>
using namespace std; const int maxn = ;
const int inf = ; int n,k;
int d[maxn],c[maxn],s[maxn],w[maxn];
int l[maxn],r[maxn]; int Minn[][<<],lazy[][<<]; void read(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%d",&d[i]);
for(int i=;i<=n;i++) scanf("%d",&c[i]);
for(int i=;i<=n;i++) scanf("%d",&s[i]);
for(int i=;i<=n;i++) scanf("%d",&w[i]);
} void push_down(int dd,int now){
if(Minn[dd][now<<] != inf){
Minn[dd][now<<] += lazy[dd][now];
lazy[dd][now<<] += lazy[dd][now];
}
if(Minn[dd][now<<|] != inf){
Minn[dd][now<<|] += lazy[dd][now];
lazy[dd][now<<|] += lazy[dd][now];
}
lazy[dd][now] = ;
} void push_up(int dd,int now){
Minn[dd][now] = min(Minn[dd][now<<],Minn[dd][now<<|]);
} void Modify(int dd,int now,int tl,int tr,int l,int r,int dt){
if(Minn[dd][now] == inf) return;
if(tl >= l && tr <= r){Minn[dd][now]+=dt; lazy[dd][now]+=dt;return;}
if(tl > r || tr < l){return;}
if(lazy[dd][now]) push_down(dd,now);
int mid = (tl+tr)/;
Modify(dd,now<<,tl,mid,l,r,dt);
Modify(dd,now<<|,mid+,tr,l,r,dt);
push_up(dd,now);
} int Query(int dd,int now,int tl,int tr,int l,int r){
if(tl >= l && tr <= r){return Minn[dd][now];}
if(tl > r || tr < l){return inf;}
if(lazy[dd][now]) push_down(dd,now);
int mid = (tl+tr)/;
int ans=min(Query(dd,now<<,tl,mid,l,r),Query(dd,now<<|,mid+,tr,l,r));
push_up(dd,now);
return ans;
} vector <int> g[maxn];
void init(){
for(int i=;i<=n;i++){
int lft = ,rgt = i;
while(lft < rgt){
int mid = (lft+rgt)/;
if(d[i]-d[mid] > s[i]) lft = mid+; else rgt = mid;
}
l[i] = lft; lft = i,rgt = n;
while(lft < rgt){
int mid = (lft+rgt+)/;
if(d[mid]-d[i] > s[i]) rgt = mid-; else lft = mid;
}
r[i] = lft;
}
for(int i=;i<=n;i++){g[r[i]+].push_back(i);}
} void work(){
init(); n++;int ans=;
for(int i=;i<=n;i++){ans += w[i]; Modify(,,,n,i,i,inf);}
for(int j=,od=;j<=k+;j++,od^=){
memset(Minn[od],,sizeof(Minn[od]));
memset(lazy[od],,sizeof(lazy[od]));
int z = c[j];
for(int i=;i<j;i++) z+=c[i],Modify(od,,,n,i,i,inf);
Modify(od,,,n,j,j,z);
int pp = ;
for(int i=;i<=n;i++){
for(int st=;st<g[i].size();st++){
Modify(od^,,,n,,l[g[i][st]]-,w[g[i][st]]);
pp += w[g[i][st]];
}
if(i <= j) continue;
Modify(od,,,n,i,i,min(Query(od^,,,n,,i-),pp)+c[i]);
}
ans = min(ans,Query(od,,,n,n,n));
}
printf("%d",ans);
} int main(){
read();
work();
return ;
}
BZOJ1835 [ZJOI2010] 基站选址 【动态规划】【线段树】的更多相关文章
- 【BZOJ1835】基站选址(线段树)
[BZOJ1835]基站选址(线段树) 题面 BZOJ 题解 考虑一个比较暴力的\(dp\) 设\(f[i][j]\)表示建了\(i\)个基站,最后一个的位置是\(j\)的最小代价 考虑如何转移\(f ...
- 【洛谷2605】[ZJOI2010] 基站选址(线段树维护DP)
点此看题面 大致题意: 有\(n\)个村庄,每个村庄有\(4\)个属性:\(D_i\)表示与村庄\(1\)的距离,\(C_i\)表示建立基站的费用,\(S_i\)表示能将其覆盖的建基站范围,\(W_i ...
- bzoj 1835 base 基站选址 - 动态规划 - 线段树
题目传送门 需要高级权限的传送门 题目大意 有$n$个村庄坐落在一条直线上,第$i \ \ \ (i>1)$个村庄距离第$1$个村庄的距离为$D_i$.需要在这些村庄中建立不超过$K$个通讯基站 ...
- [ZJOI2010]基站选址(线段树优化dp)
坑待填. \(Code\ Below:\) #include <bits/stdc++.h> #define lson (rt<<1) #define rson (rt< ...
- BZOJ1835: [ZJOI2010]base 基站选址【线段树优化DP】
Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...
- 2018.11.06 bzoj1835: [ZJOI2010]base 基站选址(线段树优化dp)
传送门 二分出每个点不需要付www贡献的范围,然后可以推出转移式子: f[i][j]=f[i−1][k]+value(k+1,j)+c[i]f[i][j]=f[i-1][k]+value(k+1,j) ...
- BZOJ 1835 [ZJOI2010]base 基站选址:线段树优化dp
传送门 题意 有 $ n $ 个村庄在一排直线上,现在要建造不超过 $ K $ 个通讯基站,基站只能造在村庄处. 第 $ i $ 个村庄距离第 $ 1 $ 个村庄的距离为 $ D_i $ .在此建造基 ...
- BZOJ 1835 基站选址(线段树优化DP)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1835 题意:有N个村庄坐落在一条直线上,第 i(i>1)个村庄距离第1个村庄的距离 ...
- bzoj1835[ZJOI2010]基站选址
主席树+决策单调,重写一遍比之前短多了……题解:http://www.cnblogs.com/liu-runda/p/6051422.html #include<cstdio> #incl ...
随机推荐
- Jvm 参数笔记
Jvm参数含义 https://cloud.tencent.com/developer/article/1129474 从一道题说起 https://blog.csdn.net/crazylzxlzx ...
- flask 跨域请求
Flask中,跨域请求主要有两种方式: 1.在响应头信息中添加允许跨域 如下,使用装饰器app.after_request(我这里的web是定义的蓝图),这样在每次请求后,加入header 2.使用第 ...
- Python-爬虫小例子-55
import re from urllib.request import urlopen def getPage(url): response = urlopen(url) return respon ...
- Python_装饰器精讲_33
from functools import wraps def wrapper(func): #func = holiday @wraps(func) def inner(*args,**kwargs ...
- 网络编程-C/S架构
什么是C/S架构 C指的是client(客户端软件),S指的是Server(服务端软件),本章的重点就是教大家写一个C/S架构的软件,实现服务端软件与客户端软件基于网络通信. 计算机基础知识 作为应用 ...
- 【转】mysql热备
mysql双机热备的实现 亲测可用
- MySQLl导入导出SQL文件
window 1.导出整个数据库 mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u dbuser -p dbname > dbname.sql ...
- 异常:fatal: unable to access 'https://git.oschina.net/pcmpcs/library.git/': Could not resolve host
git fork项目时出现的异常. 原因: 我以前用的是ssh地址做的远程通信地址,而这次是用的是https,因为很久没用,所以忘记了以前是用ssh的了.解决方案一:复制ssh协议的地址,然后再关联 ...
- 解决Window安全中心对Kitematic-0.17.3-Ubuntu.zip提示病毒,但无法删除的问题。
Trojan:JS/Tisifi.B 类型:特洛伊木马 containerfile: C:\Users\Administrator\Desktop\Kitematic-0.17.3-Ubuntu.zi ...
- Windows 10正式版历代记:Version 和 Build 对应关系
2017年10月中下旬,微软面向正式版用户推送了Windows 10创意者更新秋季版.这是自发布以来,Windows 10的第五个大版本. 在这篇文章中,我们来回顾一下Windows 10正式版的历史 ...