题目分析:

首先想一个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] 基站选址 【动态规划】【线段树】的更多相关文章

  1. 【BZOJ1835】基站选址(线段树)

    [BZOJ1835]基站选址(线段树) 题面 BZOJ 题解 考虑一个比较暴力的\(dp\) 设\(f[i][j]\)表示建了\(i\)个基站,最后一个的位置是\(j\)的最小代价 考虑如何转移\(f ...

  2. 【洛谷2605】[ZJOI2010] 基站选址(线段树维护DP)

    点此看题面 大致题意: 有\(n\)个村庄,每个村庄有\(4\)个属性:\(D_i\)表示与村庄\(1\)的距离,\(C_i\)表示建立基站的费用,\(S_i\)表示能将其覆盖的建基站范围,\(W_i ...

  3. bzoj 1835 base 基站选址 - 动态规划 - 线段树

    题目传送门 需要高级权限的传送门 题目大意 有$n$个村庄坐落在一条直线上,第$i \ \ \ (i>1)$个村庄距离第$1$个村庄的距离为$D_i$.需要在这些村庄中建立不超过$K$个通讯基站 ...

  4. [ZJOI2010]基站选址(线段树优化dp)

    坑待填. \(Code\ Below:\) #include <bits/stdc++.h> #define lson (rt<<1) #define rson (rt< ...

  5. BZOJ1835: [ZJOI2010]base 基站选址【线段树优化DP】

    Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...

  6. 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) ...

  7. BZOJ 1835 [ZJOI2010]base 基站选址:线段树优化dp

    传送门 题意 有 $ n $ 个村庄在一排直线上,现在要建造不超过 $ K $ 个通讯基站,基站只能造在村庄处. 第 $ i $ 个村庄距离第 $ 1 $ 个村庄的距离为 $ D_i $ .在此建造基 ...

  8. BZOJ 1835 基站选址(线段树优化DP)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1835 题意:有N个村庄坐落在一条直线上,第 i(i>1)个村庄距离第1个村庄的距离 ...

  9. bzoj1835[ZJOI2010]基站选址

    主席树+决策单调,重写一遍比之前短多了……题解:http://www.cnblogs.com/liu-runda/p/6051422.html #include<cstdio> #incl ...

随机推荐

  1. [C#] LINQ之LookUp

    声明:本文为www.cnc6.cn原创,转载时请注明出处,谢谢! 本文作者文采欠佳,文字表达等方面不是很好,但实际的代码例子是非常实用的,请作参考. 一.先准备要使用的类: 1.Person类: cl ...

  2. 简单的将Excel数据同步到SqlServer数据库中

    1.创建一个WinForm程序,添加一个Button控件 2.Button事件 private void button1_Click(object sender, EventArgs e) { Sys ...

  3. main函数如何调用文件外的函数

  4. scrapy之管道

    scrapy之管道 通过管道将数据持久化到数据库中,企业中常见的数据库是MySQL,分布式爬取数据时只能讲数据存储到Redis装,还可以将数据存储到本地磁盘(即写入到本地文件中). 未完待续... 0

  5. 结对项目:ATM

    一:结对项目名称:ATM 二:源代码及单元测试代码网址链接:https://github.com/tpp531853660 三:结对人的博客链接:http://www.cnblogs.com/Joan ...

  6. 阿里云ECS服务器云监控(cloudmonitor)Go语言版本插件安装卸载与维护

    云监控Go语言版本插件安装_主机监控_用户指南_云监控-阿里云https://help.aliyun.com/document_detail/97929.html 云监控cloudmonitor 1. ...

  7. java list 去重

    Guava ImmutableSet源码去重处理,Hash处理 - 汪小哥 - CSDN博客 https://blog.csdn.net/u012881904/article/details/6895 ...

  8. [转帖]2015年时微软Win3.1崩溃迫使巴黎奥利机场短暂关闭

    https://www.ithome.com/html/it/188796.htm IT之家讯 2015年11月14日消息,上周法国巴黎奥利机场因为微软的Windows 3.1系统出现故障不得不迫使所 ...

  9. [转帖]FORFILES 的简单介绍。

    FORFILES https://blog.csdn.net/sandy9919/article/details/82932460 命令格式: forfiles.exe /p "D:\备份& ...

  10. checkbox操作判断 Jquery选择器

    function checkAll(d){ console.log(d); console.log(d.checked); //注意 这里是d不是$(d) 不是jQuery对象 if(d.checke ...