Description

题库链接

给你两个整数 \(n,c\) ,以及一个数列 \(A\) ,让你将序列分为许多段。对于每一段,他的价值为序列内除了最小的 \(\left\lfloor\frac{lenth}{c}\right\rfloor\) 个元素以外的其他所有元素和, \(lenth\) 为该段的长度。最小化这个价值和。

\(1\leq n,c\leq 100000,1\leq A_i\leq 10^9\)

Solution

一个由贪心得出的结论是整个序列只要分为若干个长度为 \(c\) 的段和若干个长度为 \(1\) 的段即可。

既然要最小化价值,相当于删去的数要尽可能大。

首先分一段长度为 \(c+x,x<c\) 的段,不如分为一段为 \(c\) , \(x\) 段长度为 \(1\) 。因为无论哪种分法都只能删去一个数,但第二种考虑的范围更广一些。

其次分一段长度为 \(2c\) 的段,不如分 \(2\) 段长度为 \(c\) 的段。假设 \(2c\) 段内的最小值和次小值的位置均在前半段内;若我用第二种方法分就一定能够更优。

由此,我们令 \(f_i\) 为转移到 \(i\) 这个位置时之前的最小价值和,转移的时候只要考虑长度分为 \(1\) 和 \(c\) 的情况。对于要删去最小值,用 \(st\) 表来实现查找最值就可以了。

复杂度为 \(O(n~log_2n)\) ,瓶颈在预处理 \(st\) 表,转移是 \(O(n)\) 的。

Code

  1. //It is made by Awson on 2018.2.25
  2. #include <bits/stdc++.h>
  3. #define LL long long
  4. #define dob complex<double>
  5. #define Abs(a) ((a) < 0 ? (-(a)) : (a))
  6. #define Max(a, b) ((a) > (b) ? (a) : (b))
  7. #define Min(a, b) ((a) < (b) ? (a) : (b))
  8. #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
  9. #define writeln(x) (write(x), putchar('\n'))
  10. #define lowbit(x) ((x)&(-(x)))
  11. using namespace std;
  12. const int N = 1e5;
  13. void read(int &x) {
  14. char ch; bool flag = 0;
  15. for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
  16. for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
  17. x *= 1-2*flag;
  18. }
  19. void print(LL x) {if (x > 9) print(x/10); putchar(x%10+48); }
  20. void write(LL x) {if (x < 0) putchar('-'); print(Abs(x)); }
  21. int n, c, a[N+5], st[N+5][20], lim, limc, bin[25];
  22. LL f[N+5], sum[N+5];
  23. int query(int l, int r) {return Min(st[l][limc], st[r-bin[limc]+1][limc]); }
  24. void work() {
  25. read(n), read(c); lim = log(n)/log(2), limc = log(c)/log(2);
  26. bin[0] = 1; for (int i = 1; i <= 20; i++) bin[i] = bin[i-1]<<1;
  27. for (int i = 1; i <= n; i++) read(a[i]), st[i][0] = a[i];
  28. for (int i = 1; i <= n; i++) sum[i] = sum[i-1]+a[i];
  29. for (int t = 1; t <= lim; t++) for (int i = 1; i+bin[t]-1 <= n; i++) st[i][t] = Min(st[i][t-1], st[i+bin[t-1]][t-1]);
  30. for (int i = 1; i <= n; i++) {
  31. f[i] = f[i-1]+a[i];
  32. if (i >= c) f[i] = Min(f[i-c]+sum[i]-sum[i-c]-query(i-c+1, i), f[i]);
  33. }
  34. writeln(f[n]);
  35. }
  36. int main() {
  37. work(); return 0;
  38. }

[Codeforces 940E]Cashback的更多相关文章

  1. CodeForces - 940E - Cashback +贪心+DP

    传送门:CodeForces - 940E - Cashback 题意:在一个长度为n的数组中,可以分出长度为 k 连续的多个数组b(每个数组 b 的 k 可不相同),然后,可以对每个数组 b 进行删 ...

  2. 2018.12.29 codeforces 940E. Cashback(线性dp)

    传送门 题意:给出一个nnn个数的序列,要求将序列分成若干段,对于一段长度为kkk的自动删去最小的⌊kc⌋\left \lfloor \frac{k}{c} \right \rfloor⌊ck​⌋个数 ...

  3. CodeForces 940E

    题意略. 这个题目我开始题意理解得有点问题.本题的实质是在这个数列中选择一些数字,使得选出的这些数字之和最大,用dp来解. 我们先要明确:当我选择数列长度为2 * c时,不如把这个长度为2 * c的劈 ...

  4. Codeforces Round #466 (Div. 2) Solution

    从这里开始 题目列表 小结 Problem A Points on the line Problem B Our Tanya is Crying Out Loud Problem C Phone Nu ...

  5. DP刷题记录

    目录 dp刷题记录 codeforces 706C codeforces 940E BZOJ3997 POJ2279 GYM102082B GYM102082D codeforces132C L3-0 ...

  6. Codeforces Round #466 (Div. 2) E. Cashback

    Codeforces Round #466 (Div. 2) E. Cashback(dp + 贪心) 题意: 给一个长度为\(n\)的序列\(a_i\),给出一个整数\(c\) 定义序列中一段长度为 ...

  7. Codeforces 940 E.Cashback (单调队列,dp)

    Codeforces 940 E.Cashback 题意:一组数,要分为若干个区间,每个区间长度为ki(1<=ki<=n),并且对于每个区间删去前ki/c(向下取整)个小的数(即对区间升序 ...

  8. Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F

    Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...

  9. 【Codeforces Round #466】E. Cashback DP+ST表

    题意 给定$n$个数,将其划分成若干个连续的子序列,求最小价值,数组价值定义为,数组和减去$\lfloor \frac{k}{c} \rfloor$,$k$为数组长度,$c$为给定数 可以列得朴素方程 ...

随机推荐

  1. JavaScript(第十四天)【面向对象和原型】

    学习要点: 1.学习条件 2.创建对象 3.原型 4.继承 ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建 ...

  2. Java8学习(4)-Stream流

    Stream和Collection的区别是什么 流和集合的区别是什么? 粗略地说, 集合和流之间的差异就在于什么时候进行计算.集合是一个内存中的数据结构,它包含数据结构中目前所有的值--集合中的每个元 ...

  3. python的测试

    测试 知识点 单元测试概念 使用 unittest 模块 测试用例的编写 异常测试 测试覆盖率概念 使用 coverage 模块 实验步骤 1. 应该测试什么? 如果可能的话,代码库中的所有代码都要测 ...

  4. JAVA面向对象的多态性

    什么是多态?简而言之就是相同的行为,不同的实现. 而多态也分为静态多态(重载).动态多态(重写)和动态绑定. 静态动态,实际就是指的重载的概念,是系统在编译时,就能知晓该具体调用哪个方法.动态多态指在 ...

  5. appcompat v21: 让 Android 5.0 前的设备支持 Material Design

    1. 十大Material Design开源项目 2. appcompat v21: 让 Android 5.0 前的设备支持 Material Design 主题 AppCompat已经支持最新的调 ...

  6. New UWP Community Toolkit - RangeSelector

    概述 前面 New UWP Community Toolkit 文章中,我们对 V2.2.0 版本的重要更新做了简单回顾,其中简单介绍了 RangeSelector,本篇我们结合代码详细讲解一下 Ra ...

  7. Vim 游戏 2048

    给大家介绍一款可以在Vim里面玩的游戏 vim2048. 界面如图: 操作非常简单,可以用 hjkl 或者 上下左右方向键移动 项目开源地址为: https://github.com/wsdjeg/v ...

  8. 【bug清除】新Surface Pro使用OneNote出现毛刺现象的解决方案

    在写字的时候,左手触摸Surface的金属外壳背面,大概两个手指指肚大小.问题亲测可以得到解决. 推测是设备使用时接地没有做好,导致电磁笔出现偏移.问题初步锁定在新笔的倾斜感应上. 参考资料: htt ...

  9. 职场选择之大公司 VS 小公司

    其实这是个非常难回答的问题,很多职场新人都会有类似的顾虑和疑问. 这个问题就好比业界比较容易引起争议的编程语言哪个是最好的一样.大公司还是小公司里面发展,只有身处其中才能体会,如人饮水,冷暖自知. 笔 ...

  10. BizTalk Server 2016配置 WCF SAP Adapter

    BizTalk Server 2016配置 WCF SAP Adapter 最近公司内部需要使用BizTalk与SAP 系统进行对接,虽然SAP/PI可以以发布WebService 的方式实现与外部系 ...