Sol

设\(f[i][j]\)表示钦定\(i\)建基站,建了\(j\)个基站的最小代价

\(f[i][j]=max(f[l][j-1]+\Sigma_{t=l+1}^{i-1}\)不能影响到的村庄的\(w[t])+c[i]\)

二分处理出每个村庄\(p\)左右能影响到它的最远的基站设为\(L[p], R[p]\)

\(l,i\)不能影响到的即\(L[p]>l, R[p]<i\)

枚举\(j\),预处理出\(j=1\)的情况

线段树

每次把上次的\(f\)重建进入线段树,维护最小值

再枚举\(i\)每次加入\(R[p]\)小于\(i\)的覆盖\(1,L[p]\)

我是做到\(f[n+1]\),然后做\(k+1\)遍直接输出\(f[n+1]\)的

  1. # include <bits/stdc++.h>
  2. # define RG register
  3. # define IL inline
  4. # define Fill(a, b) memset(a, b, sizeof(a))
  5. using namespace std;
  6. typedef long long ll;
  7. const int _(1e5 + 5);
  8. IL ll Input(){
  9. RG ll x = 0, z = 1; RG char c = getchar();
  10. for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
  11. for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
  12. return x * z;
  13. }
  14. int n, k, d[_], s[_], w[_], c[_], l[_], r[_], first[_], nxt[_];
  15. int mn[_ << 2], tag[_ << 2], f[_];
  16. IL void Build(RG int x, RG int l, RG int r){
  17. tag[x] = 0;
  18. if(l == r){
  19. mn[x] = f[l];
  20. return;
  21. }
  22. RG int mid = (l + r) >> 1;
  23. Build(x << 1, l, mid), Build(x << 1 | 1, mid + 1, r);
  24. mn[x] = min(mn[x << 1], mn[x << 1 | 1]);
  25. }
  26. IL void Modify(RG int x, RG int l, RG int r, RG int L, RG int R, RG int v){
  27. if(L <= l && R >= r){
  28. mn[x] += v, tag[x] += v;
  29. return;
  30. }
  31. RG int mid = (l + r) >> 1;
  32. if(L <= mid) Modify(x << 1, l, mid, L, R, v);
  33. if(R > mid) Modify(x << 1 | 1, mid + 1, r, L, R, v);
  34. mn[x] = min(mn[x << 1], mn[x << 1 | 1]) + tag[x];
  35. }
  36. IL int Query(RG int x, RG int l, RG int r, RG int L, RG int R){
  37. if(R < L) return 0;
  38. if(L <= l && R >= r) return mn[x];
  39. RG int mid = (l + r) >> 1, ans = 2e9;
  40. if(L <= mid) ans = Query(x << 1, l, mid, L, R);
  41. if(R > mid) ans = min(ans, Query(x << 1 | 1, mid + 1, r, L, R));
  42. return ans + tag[x];
  43. }
  44. int main(RG int argc, RG char *argv[]){
  45. Fill(first, -1), n = Input(), k = Input();
  46. for(RG int i = 2; i <= n; ++i) d[i] = Input();
  47. for(RG int i = 1; i <= n; ++i) c[i] = Input();
  48. for(RG int i = 1; i <= n; ++i) s[i] = Input();
  49. for(RG int i = 1; i <= n; ++i) w[i] = Input();
  50. for(RG int i = 1; i <= n; ++i){
  51. RG int L = 1, R = i;
  52. while(L <= R){
  53. RG int mid = (L + R) >> 1;
  54. if(d[i] - d[mid] <= s[i]) R = mid - 1, l[i] = mid;
  55. else L = mid + 1;
  56. }
  57. L = i, R = n;
  58. while(L <= R){
  59. RG int mid = (L + R) >> 1;
  60. if(d[mid] - d[i] <= s[i]) L = mid + 1, r[i] = mid;
  61. else R = mid - 1;
  62. }
  63. nxt[i] = first[r[i]], first[r[i]] = i;
  64. }
  65. for(RG int i = 1, g = 0; i <= n + 1; ++i){
  66. f[i] = g + c[i];
  67. for(RG int j = first[i]; j != -1; j = nxt[j]) g += w[j];
  68. }
  69. RG int ans = f[n + 1];
  70. for(RG int p = 1; p <= k; ++p){
  71. Build(1, 1, n);
  72. for(RG int i = 1; i <= n + 1; ++i){
  73. f[i] = Query(1, 1, n, 1, i - 1) + c[i];
  74. for(RG int j = first[i]; j != -1; j = nxt[j])
  75. if(l[j] > 1) Modify(1, 1, n, 1, l[j] - 1, w[j]);
  76. }
  77. ans = min(ans, f[n + 1]);
  78. }
  79. printf("%d\n", ans);
  80. return 0;
  81. }

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个村 ...

随机推荐

  1. CSS3 文本溢出问题

    一.单行: 效果: 实现这各效果必须要加上: text-overflow: ellipsis; /*文本溢出*/ overflow: hidden; /*配合使用:溢出隐藏*/ white-space ...

  2. 高阶篇:4.2.1)DFMEA框架搭建,填写项目与要求

    本章目的:明确DFMEA的数量及目标,搭建框架,填写项目与要求. 1.步骤: 1)明确DFMEA的数量及目标: 2)搭建框架(所有DFMEA的): 3)填写项目与要求: 2.1明确DFMEA的数量及目 ...

  3. JAVA编译结果中有****$1.class的

    java编译后的文件名字带有$接数字的就是匿名内部类的编译结果,接名字的就是内部类的编译结果 例如:TestFrame$1.class是匿名内部类的编译结果,TestFrame$MyJob.class ...

  4. FreeRTOS-06任务运行时间信息统计

    根据正点原子FreeRTOS视频整理 单片机:STM32F207VC FreeRTOS源码版本:v10.0.1 * 1. 要使用vTaskGetRunTimeStats()函数,需满足以下条件: * ...

  5. shiyan 3

    //info.h#ifndef INFO_H #define INFO_H #include <string> using std::string; class Info { public ...

  6. CommandBehavior.CloseConnection有何作用

    其用在ExecuteReader(c)中,返回对象前不能关闭数据库连接,须用CommandBehavior.CloseConnection: 这是一个关于实际知识点的问题,面试官考查的是应聘者数据库访 ...

  7. MyBatis整合Spring详细教程

    1整合思路 1.SqlSessionFactory对象应该放到spring容器中作为单例存在. 2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象. 3.Mapper代理 ...

  8. 【CSS】 元素块与文字的各种居中解决方案

    元素块的居中 首先有这样一个200*200px的元素块在界面内. 元素块的水平居中: 如果想要让其水平居中,则有三种方法: 第一种是知道屏幕的长宽,则根据计算,(屏幕宽X-元素块宽Y)/ 2的结果是元 ...

  9. C 标准库 - string.h

    C 标准库 - string.h This header file defines several functions to manipulate C strings and arrays. stri ...

  10. shiro的授权

    1.授权的流程 2.三种授权方式 1.编程式:通过写if/else 授权代码块完成: Subject subject = SecurityUtils.getSubject(); if(subject. ...