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}\)不能影响到的村庄的 ...
随机推荐
- Android Toast 设置到屏幕中间,自定义Toast的实现方法,及其说明
http://blog.csdn.net/wangfayinn/article/details/8065763 Android Toast用于在手机屏幕上向用户显示一条信息,一段时间后信息会自动消失. ...
- 转:四种方案解决ScrollView嵌套ListView问题
转载自:http://blog.sina.com.cn/s/blog_46798aa80101lxbk.html 原始的连接已经不知道是哪里了,项目中遇到了同样的问题,花了一下午都没有想到是嵌套引起的 ...
- 【C#】获取本地Cookie的问题
using System; using System.Net; using System.IO; using System.Text; // // TODO: 在此处添加代码以启动应用程序 // st ...
- 主机访问 虚拟机web注意事项
在这里, 我通过NAT的方式, 通过主机访问虚拟机. 需要做的是, 将主机中访问的端口, 映射为虚拟机的'编辑->虚拟网络编辑器->vmnet8', 如下图 在弹出的'映射传入端口'界面中 ...
- 什么情况下会调用到session_destroy()
https://segmentfault.com/q/1010000000191102 首先 ... session_destory() 是一个函数 ... 这个函数在任何情况下都不会被 php 引擎 ...
- Object-C内存管理
Object-C的内存管理是基于引用计数的.你要做的事情只是关注你的引用,而释放内存的工作实际上由运行环境完成. 在最简单的情形中,你分配(alloc)的对象,或只是保留(retain)在一些地方的对 ...
- 国庆第六日(2014年10月6日11:51:15),node-webkit,理财产品
(1)node-webkit:一篇很好的入门文章.入门.系列. 在window下的打包和运行.大漠的一篇讲解文章 . (2)lighttable: 官网. (3)现在的理财产品,雨后春笋般冒出:宝点网 ...
- 九度OJ 1433 FatMouse -- 贪心算法
题目地址:http://ac.jobdu.com/problem.php?pid=1433 题目描述: FatMouse prepared M pounds of cat food, ready to ...
- Python中 if __name__ == '__main__': 详解
一个python文件就可以看作是一个python的模块,这个python模块(.py文件)有两种使用方式:直接运行和作为模块被其他模块调用. __name__:每一个模块都有一个内置属性__name_ ...
- AMAZON PRICE TRACKER, AMAZON PRICE HISTORY, AMAZON PRICE DROP ALERT | DROPGG.COM
DropGG.com is the destination for savvy shoppers looking to save money by buying smart. DropGG.com a ...