bzoj1835
最近状态太差,先补补结题报告吧
这是一道好题
设f[i,j]表示到第j个位置建了i个基站且第j个位置建了基站的最小花费
不难得到f[i,j]=min(f[i-1,k]+cost[k+1,j])+c[j];
首先为了方便计算假定在两端无穷远处还要建一个基站(方便统计)
i我们是可以滚动的不管他,问题就是如何解决cost
也就是两个基站间的村庄的补偿费
我们设每个村庄i向左最远能收到l[i]位置上基站的信号,向右最远r[i]
不难发现,随着j的递增,cost[k]是呈上升趋势的
也就是,对于当前j,那些r[p]<j的点p,向右是永远收不到信号了,
向左对于在位置k∈[0,l[p]-1]的基站,随着j增加以k,j为端点建基站对于p是永远要收补偿费的
于是我们令cost[k]表示(k建基站)到当前点之间村庄要收补偿费的和
对于当前点j,我们找出r[p]+1=j的点p,对于k∈[0,l[p]-1] cost[k]+w[p]
显然是区间查询,区间修改的问题,我们可以用线段树解决
复杂度O(knlogn)
type node=record
po,next:longint;
end; var f,c,d,p,w,s,l:array[..] of longint;
e:array[..] of node;
tree,lazy:array[..*] of longint;
ans,n,m,i,j,k,t,x:longint; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure update(i:longint);
begin
tree[i]:=min(tree[i*],tree[i*+]);
end; procedure push(i:longint);
begin
inc(lazy[i*],lazy[i]);
inc(lazy[i*+],lazy[i]);
inc(tree[i*],lazy[i]);
inc(tree[i*+],lazy[i]);
lazy[i]:=;
end; function fl(l,r,x:longint):longint;
var m:longint;
begin
fl:=r;
while l<=r do
begin
m:=(l+r) shr ;
if d[m]>=x then
begin
fl:=m;
r:=m-;
end
else l:=m+;
end;
end; function fr(l,r,x:longint):longint;
var m:longint;
begin
fr:=l;
while l<=r do
begin
m:=(l+r) shr ;
if d[m]<=x then
begin
fr:=m;
l:=m+;
end
else r:=m-;
end;
end; procedure build(i,l,r:longint);
var m:longint;
begin
lazy[i]:=;
if l=r then
begin
tree[i]:=f[l];
lazy[i]:=;
end
else begin
m:=(l+r) shr ;
build(i*,l,m);
build(i*+,m+,r);
update(i);
end;
end; procedure work(i,l,r,x,y:longint);
var m:longint;
begin
if r<=x then
begin
inc(lazy[i],y);
inc(tree[i],y);
end
else begin
if lazy[i]<> then push(i);
m:=(l+r) shr ;
work(i*,l,m,x,y);
if x>m then work(i*+,m+,r,x,y);
update(i);
end;
end; function ask(i,l,r,x:longint):longint;
var m,s:longint;
begin
if r<=x then exit(tree[i])
else begin
if lazy[i]<> then push(i);
m:=(l+r) shr ;
s:=ask(i*,l,m,x);
if x>m then s:=min(s,ask(i*+,m+,r,x));
exit(s);
end;
end; begin
readln(n,m);
for i:= to n do
read(d[i]);
for i:= to n do
read(c[i]);
for i:= to n do
read(s[i]);
for i:= to n do
begin
read(w[i]);
ans:=ans+w[i];
end;
for i:= to n do
begin
l[i]:=fl(,i,d[i]-s[i]);
x:=fr(i,n,d[i]+s[i]);
inc(t);
e[t].po:=i;
e[t].next:=p[x+];
p[x+]:=t;
end;
for i:= to m do
begin
build(,,n);
for j:= to n+ do
begin
k:=p[j];
while k<> do
begin
work(,,n,l[e[k].po]-,w[e[k].po]);
k:=e[k].next;
end;
if i= then x:= else x:=j-;
f[j]:=ask(,,n,x)+c[j];
end;
ans:=min(ans,f[n+]);
end;
build(,,n);
for j:= to n+ do
begin
k:=p[j];
while k<> do
begin
work(,,n,l[e[k].po]-,w[e[k].po]);
k:=e[k].next;
end;
end;
ans:=min(ans,ask(,,n,n));
writeln(ans);
end.
bzoj1835的更多相关文章
- 【BZOJ1835】基站选址(线段树)
[BZOJ1835]基站选址(线段树) 题面 BZOJ 题解 考虑一个比较暴力的\(dp\) 设\(f[i][j]\)表示建了\(i\)个基站,最后一个的位置是\(j\)的最小代价 考虑如何转移\(f ...
- 【BZOJ1835】[ZJOI2010]base 基站选址 线段树+DP
[BZOJ1835][ZJOI2010]base 基站选址 Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯 ...
- bzoj1835[ZJOI2010]base基站选址
据说正解是什么线段树优化DP,但是作为脑子有坑选手,我们需要5k的做法: 主席树+决策单调性..... F[m][i]表示已经放置了m个基站,第m个基站放置在第i个村庄,第i个村庄及之前的村庄的总最少 ...
- 【BZOJ1835】【ZJOI2010】基站选址
原题传送门 Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距 ...
- BZOJ1835 [ZJOI2010] 基站选址 【动态规划】【线段树】
题目分析: 首先想一个DP方程,令f[m][n]表示当前在前n个村庄选了m个基站,且第m个基站放在n处的最小值,转移可以枚举上一个放基站的村庄,然后计算两个村庄之间的代价. 仔细思考两个基站之间村庄的 ...
- 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) ...
- BZOJ1835,LG2605 [ZJOI2010]基站选址
题意 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为\(D_i\) 需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为\(C_i\) 如果在距离第i个村 ...
- BZOJ1835: [ZJOI2010]base 基站选址【线段树优化DP】
Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...
- Bzoj1835:[ZJOI2010]基站选址
Sol 设\(f[i][j]\)表示钦定\(i\)建基站,建了\(j\)个基站的最小代价 \(f[i][j]=max(f[l][j-1]+\Sigma_{t=l+1}^{i-1}\)不能影响到的村庄的 ...
随机推荐
- rc4加密
function RC4(Expression, Password: string): string; var RB : array[0..255] of Integer; X, Y, Z: long ...
- linux mysql目录详解
1.mysql数据库目录 /var/lib/mysql 2.mysql配置文件目录 /usr/share/mysql 3.相关命令目录 /usr/bin 4.启动脚本目录
- redhat5.8无法进入图形界面
解决办法: 删除/etc/X11/xorg.conf文件
- AutoLayout的一些注意事项
要了解autolayout 首先要知道程序视图启动顺序: -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; ...
- JS实现回到页面顶部动画效果 2016.03.23
最近在模仿各大网站写页面样式和交互,发现好多都有回到顶部的需要,所以写了一下js,记录下来. 发现还可以添加从快到慢的动画效果和随时下拉滚动条停止滚动的功能, 参考了imooc上相关课程,最终实现JS ...
- maven使用之烦人的.lastUpdated文件
项目使用maven管理jar包,很容易因为各种原因(网速慢.断网)导致jar包下载不下来,出现很多.lastUpdated文件.这些文件一个一个删除太麻烦.下面是全部删除的方法 windows系统 c ...
- JPA的泛型DAO设计及使用
使用如Hibernate或者JPA作为持久化的解决方案时,设计一个泛型的DAO抽象父类可以方便各个实体的通用CRUD操作.由于此时大部分实体DAO的CRUD操作基本一样,采用泛型设计解决这个问题,带来 ...
- erlang 编程指南 第三章-顺序编程 课后练习
1. sum(3) => 6; sum(1,3) => 6; sum(6,6) => 6; sum(N) when is_integer(N) -> sum_acc(N,0); ...
- mod_wsgi
配置: WSGIScriptAlias /var/www/wsgi-scripts/simple.wsgi def application(environ, start_response): outp ...
- OpenCV2学习笔记02:MSVC2013搭建OpenCV开发环境
我这里编译的库是通过手动编译的.只是需要注意的是,手动编译一般会产生大量的文件,差不多7个多G的样子,实在是有点浪费硬盘存储呀,其实我们可以删除掉没有用的东西.因为我们在编译的时候指定了一个目录比如我 ...