设f[i][j]表示在第i个村庄建第j个基站的花费

那么有$f[i][j]=min\{f[k][j-1]+w[k,i]\}$,其中w[k,i]表示在k,i建基站,k,i中间的不能被满足的村庄的赔偿金之和

如果把每个村庄能被满足的区间处理出来,记做$[l_i,r_i]$,那么i,j不能满足的村庄,就是$i<l,r<j$的村庄

考虑将$f[i][k]+w[i,j]$的i固定,而j随着dp进行而变化,这样维护K个线段树

那么当j越来越大,会有更多的村庄[l,r]变得满足r<j,被加入到线段树的区间[1,l-1]中

用堆来维护这些村庄,按r从大到小排序即可

复杂度$O(nklogn)$

  1. #include<bits/stdc++.h>
  2. #define pa pair<ll,ll>
  3. #define CLR(a,x) memset(a,x,sizeof(a))
  4. #define MP make_pair
  5. using namespace std;
  6. typedef long long ll;
  7. const int maxn=2e4+,maxk=;
  8.  
  9. inline char gc(){
  10. return getchar();
  11. static const int maxs=<<;static char buf[maxs],*p1=buf,*p2=buf;
  12. return p1==p2&&(p2=(p1=buf)+fread(buf,,maxs,stdin),p1==p2)?EOF:*p1++;
  13. }
  14. inline ll rd(){
  15. ll x=;char c=gc();bool neg=;
  16. while(c<''||c>''){if(c=='-') neg=;c=gc();}
  17. while(c>=''&&c<='') x=(x<<)+(x<<)+c-'',c=gc();
  18. return neg?(~x+):x;
  19. }
  20.  
  21. int N,K,f[maxn][maxk],pos[maxn],cost[maxn];
  22. struct Node{
  23. int l,r,w;
  24. }p[maxn];
  25. int mi[maxk*maxn*],laz[maxk*maxn*],ch[maxk*maxn*][],rt[maxk],pct;
  26. inline bool operator < (Node a,Node b){return a.r>b.r;}
  27. priority_queue<Node> q;
  28.  
  29. inline void tag(int p,int v){
  30. mi[p]+=v,laz[p]+=v;
  31. }
  32.  
  33. inline void pushdown(int p){
  34. if(!laz[p]) return;
  35. int a=ch[p][],b=ch[p][];
  36. if(a) tag(a,laz[p]);
  37. if(b) tag(b,laz[p]);
  38. laz[p]=;
  39. }
  40. inline void update(int p){
  41. mi[p]=min(mi[ch[p][]],mi[ch[p][]]);
  42. }
  43.  
  44. inline void add(int p,int l,int r,int x,int y,int z){
  45. if(x<=l&&r<=y) tag(p,z);
  46. else{
  47. pushdown(p);int m=l+r>>;
  48. if(x<=m) add(ch[p][],l,m,x,y,z);
  49. if(y>=m+) add(ch[p][],m+,r,x,y,z);
  50. update(p);
  51. }
  52. }
  53.  
  54. inline int query(int p,int l,int r,int x,int y){
  55. if(x<=l&&r<=y) return mi[p];
  56. int m=l+r>>;pushdown(p);int re=1e9;
  57. if(x<=m) re=query(ch[p][],l,m,x,y);
  58. if(y>=m+) re=min(re,query(ch[p][],m+,r,x,y));
  59. return re;
  60. }
  61.  
  62. inline void change(int p,int l,int r,int x,int y){
  63. if(l==r) mi[p]=y;
  64. else{
  65. int m=l+r>>;pushdown(p);
  66. if(x<=m) change(ch[p][],l,m,x,y);
  67. else change(ch[p][],m+,r,x,y);
  68. update(p);
  69. }
  70. }
  71.  
  72. inline void build(int &p,int l,int r){
  73. p=++pct;mi[p]=1e9+;
  74. if(l<r){
  75. int m=l+r>>;
  76. build(ch[p][],l,m);build(ch[p][],m+,r);
  77. }
  78. }
  79.  
  80. int main(){
  81. //freopen("","r",stdin);
  82. int i,j,k;
  83. N=rd(),K=rd();
  84. for(i=;i<=N;i++)
  85. pos[i]=rd();
  86. for(i=;i<=N;i++)
  87. cost[i]=rd();
  88. pos[N+]=1e9+;
  89. for(i=;i<=N;i++){
  90. int s=rd();
  91. p[i].l=lower_bound(pos+,pos+N+,pos[i]-s)-pos;
  92. p[i].r=upper_bound(pos+,pos+N+,pos[i]+s)-pos-;
  93. }
  94. for(i=;i<=N;i++)
  95. p[i].w=rd();
  96. p[N+].l=N+,p[N+].r=N+,p[N+].w=,N++,K++;
  97. CLR(f,);f[][]=;
  98. for(i=;i<=K;i++) build(rt[i],,N);
  99. for(i=;i<=N;i++){
  100. while(!q.empty()){
  101. Node p=q.top();
  102. if(p.r>=i) break;
  103. q.pop();f[][]+=p.w;
  104. for(k=;k<=min(p.l-,K);k++)
  105. add(rt[k],,N,,p.l-,p.w);
  106. }
  107. f[i][]=f[][]+cost[i];change(rt[],,N,i,f[i][]);
  108. for(k=;k<=min(i,K);k++){
  109. f[i][k]=query(rt[k-],,N,,i-)+cost[i];
  110. change(rt[k],,N,i,f[i][k]);
  111. }
  112. q.push(p[i]);
  113. }
  114. int ans=2e9;
  115. for(i=;i<=K;i++) ans=min(ans,f[N][i]);
  116. printf("%d\n",ans);
  117. return ;
  118. }

luogu2605 基站选址 (线段树优化dp)的更多相关文章

  1. 洛谷$P2605\ [ZJOI2010]$基站选址 线段树优化$dp$

    正解:线段树优化$dp$ 解题报告: 传送门$QwQ$ 难受阿,,,本来想做考试题的,我还造了个精妙无比的题面,然后今天讲$dp$的时候被讲到了$kk$ 先考虑暴力$dp$?就设$f_{i,j}$表示 ...

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

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

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

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

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

    题目大意:略 洛谷题面传送门 BZOJ题面传送门 注意题目的描述,是村庄在一个范围内去覆盖基站,而不是基站覆盖村庄,别理解错了 定义$f[i][k]$表示只考虑前i个村庄,一共建了$k$个基站,最后一 ...

  5. BZOJ1835: [ZJOI2010]base 基站选址(线段树优化Dp)

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

  6. Codeforces Round #426 (Div. 2) D 线段树优化dp

    D. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  7. BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】

    BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...

  8. [AGC011F] Train Service Planning [线段树优化dp+思维]

    思路 模意义 这题真tm有意思 我上下楼梯了半天做出来的qwq 首先,考虑到每K分钟有一辆车,那么可以把所有的操作都放到模$K$意义下进行 这时,我们只需要考虑两边的两辆车就好了. 定义一些称呼: 上 ...

  9. 【bzoj3939】[Usaco2015 Feb]Cow Hopscotch 动态开点线段树优化dp

    题目描述 Just like humans enjoy playing the game of Hopscotch, Farmer John's cows have invented a varian ...

随机推荐

  1. 开发工具之Sublime编辑器

    sublime是一款轻量级的编辑器,可以从官网上进行下载最新版本.它有很多使用并且强大的功能支持.例如:GOTO,package 等快捷操作.但有时候下载的版本不能进行安装package contro ...

  2. [官网]Red Hat Enterprise Linux Release Dates

    Red Hat Enterprise Linux Release Dates https://access.redhat.com/articles/3078 The tables below list ...

  3. OpenCV__type()返回的数字

    OpenCV中的类型以宏定义的形式给出 type_c.h中片段 #define CV_CN_MAX 512 #define CV_CN_SHIFT 3 #define CV_DEPTH_MAX (1 ...

  4. sqlserver常用语法

    --临时表 IF OBJECT_ID('tempdb..#Entry') is not null BEGIN   DROP TABLE #Entry   END ------------------- ...

  5. 二叉搜索树的第k个节点

    给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8)    中,按结点数值大小顺序第三小结点的值为4. = =一看就想到中序遍历 public class Soluti ...

  6. VS code常用快捷方式—转载

    http://www.cnblogs.com/weihe-xunwu/p/6687000.html

  7. Spring拦截器(学习笔记)

    SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的 在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式 第一种方 ...

  8. 创建简单的表单Demo

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 所活天数!java Date应用

    package cn.jiu.com; import java.text.ParseException; import java.text.SimpleDateFormat; import java. ...

  10. U68641 划水(swim.pas/c/cpp)

    U68641 划水(swim.pas/c/cpp) 题目背景 小小迪带你划水. 题目描述 原题 输入输出格式 输入格式: 第一行一个数 T. 接下来 T 行每行一个数表示 n 输出格式: 输出 T 行 ...