原题传送门

Description

有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di。需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci。如果在距离第i个村庄不超过Si的范围内建立了一个通讯基站,那么就成它被覆盖了。如果第i个村庄没有被覆盖,则需要向他们补偿,费用为Wi。现在的问题是,选择基站的位置,使得总费用最小。 输入数据 (base.in) 输入文件的第一行包含两个整数N,K,含义如上所述。 第二行包含N-1个整数,分别表示D2,D3,…,DN ,这N-1个数是递增的。 第三行包含N个整数,表示C1,C2,…CN。 第四行包含N个整数,表示S1,S2,…,SN。 第五行包含N个整数,表示W1,W2,…,WN。

Input

输入文件的第一行包含两个整数N,K,含义如上所述。

第二行包含N-1个整数,分别表示D2,D3,…,DN ,这N-1个数是递增的。

第三行包含N个整数,表示C1,C2,…CN。

第四行包含N个整数,表示S1,S2,…,SN。

第五行包含N个整数,表示W1,W2,…,WN。

Output

输出文件中仅包含一个整数,表示最小的总费用。

Sample Input

3 2

1 2

2 3 2

1 1 0

10 20 30

Sample Output

4

Hint

40%的数据中,\(N \leq 500\);

100%的数据中,\(K \leq N,K \leq 100 , N \leq 20000 , Di \leq 10^{9} , Ci \leq 10000,Si \leq 10^9,Wi \leq 10000\) 。

Solution

对于 40%的数据,显然,这是一个简单的 dp,定义 \(f_{i,j}\) 表示将第 i 个星球选为第 j 个基站且不考虑之后的星球的费用,显然可以很容易的得到 dp 方程:$f_{i,j} = min(f_{k,j-1} + cost(k,i))+c_{i} $ ;

上文中 $ Cost(i,j) = \Sigma_{k} w_{k} ( d_{i} < d_{k} - s_{k} \wedge d_{k} > d_{j} + s_{k} ) $ 表示 i~j 之间没有被覆盖到的星球的花费之和。暴力计算 cost 函数的时间复杂度为 O(n),故总时间复杂度为\(O(kn^2)\) .

对于 100%的数据,考虑进行优化,首先发现,第 j 层的状态只与上一层有关,故考虑压内存,j接下来,我们发现,大量的时间花费计算在 cost 函数上,容易发现,对于一个星球 i,它可以被覆盖的范围一定是一个区间,考虑记录这个区间的左右端点,接下来考虑它没被覆盖的贡献,容易发现,当你选择区间右端点(不含)之后作为即将建立的基站时,若是从左端点(不含)之前的星球所转移过来的,就需要花费该星球的未覆盖费,由于这是一个区间问题,而状态的转移\(min(f_{j} + cost(j,i))\)也同样是区间内的,因此考虑利用线段树维护\(min(f_{j} + cost(j,i))\)加速 DP,滚动利用线段树,在推导完第 i 个星球之后,将右端点为 i 的星球的\(w_{j}\)在线段树上累加到该星球左端点(不含)之前的星球即可,这样处理好细节之后就可以通过此题,时间复杂度为\(O(kn \log_{2} n)\),空间复杂度为O(n).

Code

  1. #include <stdio.h>
  2. #define R register
  3. #define mid (l+r>>1)
  4. #define MN 20005
  5. #define MM (1<<16)
  6. #define inf 0x3f3f3f3f
  7. inline int read(){
  8. R int x; R bool f; R char c;
  9. for (f=0; (c=getchar())<'0'||c>'9'; f=c=='-');
  10. for (x=c-'0'; (c=getchar())>='0'&&c<='9'; x=(x<<3)+(x<<1)+c-'0');
  11. return f?-x:x;
  12. }
  13. int d[MN],T[MM],mark[MM],r[MN],c[MN],w[MN],st[MN],ed[MN],n,k,lk[MN],nxt[MN],head[MN],cnt,f[MN],ans=inf;
  14. inline int min(int a,int b) {return a<b?a:b;}
  15. inline void ins(int x,int y){lk[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;}
  16. inline int find(int x){
  17. R int l=1,r=n;
  18. while(l<r)
  19. if (d[mid]<x) l=mid+1;
  20. else r=mid;
  21. return l;
  22. }
  23. inline void build(int k,int l,int r){
  24. if (l==r){
  25. T[k]=f[l];
  26. return;
  27. }build(k<<1,l,mid);
  28. build(k<<1|1,mid+1,r);
  29. T[k]=min(T[k<<1],T[k<<1|1]);mark[k]=0;
  30. }
  31. inline void pushdown(int k){
  32. if (!mark[k]) return;
  33. T[k<<1]+=mark[k],T[k<<1|1]+=mark[k];
  34. mark[k<<1]+=mark[k],mark[k<<1|1]+=mark[k];
  35. mark[k]=0;
  36. }
  37. inline void update(int l,int r,int a,int b,int k,int ad){
  38. if (l>=a&&r<=b){
  39. T[k]+=ad;
  40. mark[k]+=ad;
  41. return;
  42. }pushdown(k);
  43. if (a<=mid) update(l,mid,a,b,k<<1,ad);
  44. if (b>mid) update(mid+1,r,a,b,k<<1|1,ad);
  45. T[k]=min(T[k<<1],T[k<<1|1]);
  46. }
  47. inline int query(int l,int r,int a,int b,int k){
  48. if (l==a&&r==b) return T[k];pushdown(k);
  49. if (b<=mid) return query(l,mid,a,b,k<<1);
  50. if (a>mid) return query(mid+1,r,a,b,k<<1|1);
  51. return min(query(l,mid,a,mid,k<<1),query(mid+1,r,mid+1,b,k<<1|1));
  52. }
  53. int main(){
  54. n=read(),k=read();
  55. for (R int i=2; i<=n; ++i) d[i]=read();
  56. for (R int i=1; i<=n; ++i) c[i]=read();
  57. for (R int i=1; i<=n; ++i) r[i]=read();
  58. for (R int i=1; i<=n; ++i) w[i]=read();
  59. d[++n]=inf;++k;
  60. for (R int i=1; i<=n; ++i){
  61. st[i]=find(d[i]-r[i]),ed[i]=find(d[i]+r[i]);
  62. if (d[ed[i]]>r[i]+d[i]) --ed[i];
  63. ins(ed[i],i);
  64. }
  65. for (R int i=1,sum=0; i<=n; ++i){
  66. f[i]=sum+c[i];
  67. for (R int j=head[i]; j; j=nxt[j])
  68. sum+=w[lk[j]];
  69. }
  70. for (R int i=2; i<=k; ++i){
  71. build(1,1,n);
  72. for (R int j=1; j<=n; ++j){
  73. if (j>=i)
  74. f[j]=query(1,n,1,j-1,1)+c[j];
  75. else f[j]=inf;
  76. for (R int l=head[j]; l; l=nxt[l])
  77. if (st[lk[l]]>1)
  78. update(1,n,1,st[lk[l]]-1,1,w[lk[l]]);
  79. }
  80. }
  81. printf("%d\n",f[n]);
  82. return 0;
  83. }

【BZOJ1835】【ZJOI2010】基站选址的更多相关文章

  1. BZOJ1835 [ZJOI2010] 基站选址 【动态规划】【线段树】

    题目分析: 首先想一个DP方程,令f[m][n]表示当前在前n个村庄选了m个基站,且第m个基站放在n处的最小值,转移可以枚举上一个放基站的村庄,然后计算两个村庄之间的代价. 仔细思考两个基站之间村庄的 ...

  2. bzoj1835[ZJOI2010]基站选址

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

  3. 【题解】Luogu P2605 [ZJOI2010]基站选址

    原题传送门:P2604 [ZJOI2010]基站选址 看一眼题目,变知道这题一定是dp 设f[i][j]表示在第i个村庄修建第j个基站且不考虑i+1~n个村庄的最小费用 可以得出f[i][j] = M ...

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

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

  5. 【LG2605】[ZJOI2010]基站选址

    [LG2605][ZJOI2010]基站选址 题面 洛谷 题解 先考虑一下暴力怎么写,设\(f_{i,j}\)表示当前\(dp\)到\(i\),且强制选\(i\),目前共放置\(j\)个的方案数. 那 ...

  6. 题解 [ZJOI2010]基站选址

    题解 [ZJOI2010]基站选址 题面 解析 首先考虑一个暴力的DP, 设\(f[i][k]\)表示第\(k\)个基站设在第\(i\)个村庄,且不考虑后面的村庄的最小费用. 那么有\(f[i][k] ...

  7. luogu P2605 [ZJOI2010]基站选址 线段树优化dp

    LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cd ...

  8. [ZJOI2010]基站选址,线段树优化DP

    G. base 基站选址 内存限制:128 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较   题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离 ...

  9. BZOJ1835,LG2605 [ZJOI2010]基站选址

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

  10. Bzoj1835:[ZJOI2010]基站选址

    Sol 设\(f[i][j]\)表示钦定\(i\)建基站,建了\(j\)个基站的最小代价 \(f[i][j]=max(f[l][j-1]+\Sigma_{t=l+1}^{i-1}\)不能影响到的村庄的 ...

随机推荐

  1. Spring Boot 配置文件详解

    Spring Boot配置文件详解 Spring Boot提供了两种常用的配置文件,分别是properties文件和yml文件.他们的作用都是修改Spring Boot自动配置的默认值.相对于prop ...

  2. Python之旅.第二章数据类型 3.19/3.20/3.21/3.22/3.23

    一.数字类型 1.int类型: 基本使用: 用途:用于年龄,手机号,身份证号: 定义: age=18: 常用操作+内置方法: 正常的运算赋值: 进制转换: print(bin(3)); 把十进制3转换 ...

  3. Oracle 使用pl/sql将表中的数据读出到文件中

    (1)在服务器上创建文件路径及文件 [oracle@redhat errormsg]$ touch test01.txt (2)在数据库中创建路径及授权 (3)创建存储过程 CREATE OR REP ...

  4. Mosquito集群模式

    参考链接: http://blog.csdn.net/z729685731/article/details/70142182 http://blog.csdn.net/yuhaiyang457288/ ...

  5. 阿里云API网关(9)常见问题

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  6. HTML mate标签

    META标签分两大部分:HTTP标题信息(http-equiv)和页面描述信息(name). http-equiv http-equiv类似于HTTP的头部协议,它回应给浏览器一些有用的信息,以帮助正 ...

  7. IDEA安装和JDK的配置

    安装: 免费获取注册码:   http://idea.lanyus.com/ 将其压缩包解压后:  应用程序在bin目录下 打开之后: 选择第二个,输入刚获取的验证码: 成功. 如果没有安装JDK报错 ...

  8. python 杂货铺

    python 杂货铺之不知道的python操作 1.交互模式下的神奇的_ windos中cmd交互模式中下(python2,python3),最近一个表达式的值赋给变量 _.这样我们就可以把它当作一个 ...

  9. Oracle12c:支持通过创建identity columen来实现创建自增列

    oracle12c之前如果需要创建自增列必须要通过sequence+trigger来实现.但是oracle12c已经可以像mysql,sqlserver一样通过identity column来设置自增 ...

  10. asp.net core 六 Oracle ORM

         .netcore 中 Oracle ORM      在真正将项目移植到.netcore下,才发现会有很多问题,例如访问Oracle,问题出现的时间在2017年底          参考连接 ...