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}\)不能影响到的村庄的 ...
随机推荐
- 解析包时出现错误,用代码安装apk出现问题
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file),"appli ...
- Android Animation 动画属性
在 Android 中, Animation 动画效果的实现可以通过两种方式进行实现: 一种是 tweened animation 渐变动画,另一种是 frame by frame animation ...
- 【转载】Oracle层次查询和分析函数
摘要 一组连续的数,去掉中间一些数,如何求出剩下的数的区间(即号段)?知道号段的起止,如何求出该号段内所有的数?知道一个大的号段范围和已经取过的号段,如何求出可用的号段?利用Oracle提供的强大的查 ...
- LIBPNG使用小结(二)
之前写的LIBPNG库学习小结介绍了怎么样自定义LIBPNG库的write.read.flush函数,而不使用LIBPNG库提供的默认函数. 上一篇讲述的都是在单线程的情况下,今天将程序升级,放在多线 ...
- stack around the variable “XX” was corrupted
晚上花了几个小时fix了这个恼人的BUG!“在变量XX周围的堆栈已损坏” 在网上找到的解释是: 把“project->配置属性->c/c++->代码生成->基本运行时检查 设置 ...
- ES6笔记-字符串方法
字符串检索方法,indexOf(searchValue,fromIndex)//参数1必需,检索查询的字符串或者值,参数2选题,规定检索的起始位置,不设置默认从0开始 indexOf()方法返回检索字 ...
- SQL Cursor(游标)
1.游标在数据表没有id(identity(1,1))时好用,但是游标会吃更多的内存,减少可用的并发,占用宽带,锁定资源,当然还有更多的代码量 2.如果能不用游标,尽量不要使用游标,用完用完之后一定要 ...
- Visual Studio2012中搭建WCF项目
分布式系统:指在系统与系统之间进行通信,系统不再是孤立的,例如:淘宝查看物流信息,或是hao123的天气预报,这些可能都是用的别的系统的web方法. 1.创建空的解决方案 2.新建项目-WCF服务库项 ...
- 微信公众号-加解密数据demo坑
demo里面的MsgSignature作为url参数一部分了,demo也不更新下 坑爹的微信! 解密信息部分 include_once "wxBizMsgCrypt.php"; $ ...
- yii 缓存探究
1.在配置文件中 //在权威指南上是'cache' 其实可以根据不同的缓存组件起不同的名称 //memcache缓存 'memcache' => array( 'class' => 'sy ...