[Codeforces 940E]Cashback
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
//It is made by Awson on 2018.2.25
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 1e5;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(LL x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(LL x) {if (x < 0) putchar('-'); print(Abs(x)); }
int n, c, a[N+5], st[N+5][20], lim, limc, bin[25];
LL f[N+5], sum[N+5];
int query(int l, int r) {return Min(st[l][limc], st[r-bin[limc]+1][limc]); }
void work() {
read(n), read(c); lim = log(n)/log(2), limc = log(c)/log(2);
bin[0] = 1; for (int i = 1; i <= 20; i++) bin[i] = bin[i-1]<<1;
for (int i = 1; i <= n; i++) read(a[i]), st[i][0] = a[i];
for (int i = 1; i <= n; i++) sum[i] = sum[i-1]+a[i];
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]);
for (int i = 1; i <= n; i++) {
f[i] = f[i-1]+a[i];
if (i >= c) f[i] = Min(f[i-c]+sum[i]-sum[i-c]-query(i-c+1, i), f[i]);
}
writeln(f[n]);
}
int main() {
work(); return 0;
}
[Codeforces 940E]Cashback的更多相关文章
- CodeForces - 940E - Cashback +贪心+DP
传送门:CodeForces - 940E - Cashback 题意:在一个长度为n的数组中,可以分出长度为 k 连续的多个数组b(每个数组 b 的 k 可不相同),然后,可以对每个数组 b 进行删 ...
- 2018.12.29 codeforces 940E. Cashback(线性dp)
传送门 题意:给出一个nnn个数的序列,要求将序列分成若干段,对于一段长度为kkk的自动删去最小的⌊kc⌋\left \lfloor \frac{k}{c} \right \rfloor⌊ck⌋个数 ...
- CodeForces 940E
题意略. 这个题目我开始题意理解得有点问题.本题的实质是在这个数列中选择一些数字,使得选出的这些数字之和最大,用dp来解. 我们先要明确:当我选择数列长度为2 * c时,不如把这个长度为2 * c的劈 ...
- Codeforces Round #466 (Div. 2) Solution
从这里开始 题目列表 小结 Problem A Points on the line Problem B Our Tanya is Crying Out Loud Problem C Phone Nu ...
- DP刷题记录
目录 dp刷题记录 codeforces 706C codeforces 940E BZOJ3997 POJ2279 GYM102082B GYM102082D codeforces132C L3-0 ...
- Codeforces Round #466 (Div. 2) E. Cashback
Codeforces Round #466 (Div. 2) E. Cashback(dp + 贪心) 题意: 给一个长度为\(n\)的序列\(a_i\),给出一个整数\(c\) 定义序列中一段长度为 ...
- Codeforces 940 E.Cashback (单调队列,dp)
Codeforces 940 E.Cashback 题意:一组数,要分为若干个区间,每个区间长度为ki(1<=ki<=n),并且对于每个区间删去前ki/c(向下取整)个小的数(即对区间升序 ...
- Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F
Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...
- 【Codeforces Round #466】E. Cashback DP+ST表
题意 给定$n$个数,将其划分成若干个连续的子序列,求最小价值,数组价值定义为,数组和减去$\lfloor \frac{k}{c} \rfloor$,$k$为数组长度,$c$为给定数 可以列得朴素方程 ...
随机推荐
- location和location.href跳转url的区别
使用 location = url 跳转,如果本地之前已经载入过该页面并有缓存,那么会直接读取本地的缓存,缓存机制是由本地浏览器设置决定的.状态码为: 200 OK (from cache) . ...
- Java基础学习笔记二十一 多线程
多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念.进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线 ...
- Linux 终端 Bash 常用快捷键介绍及经验
1. 最重要的自动补全 命令 解释 Tab 自动补全 不用多说,自动补全可以节省大量时间 2. 编辑跳转 命令 解释 Ctrl + A 跳转到当前行首 Ctrl + E 跳转到当前行末 Alt + F ...
- 在Winform混合式框架中整合外部API接口的调用
在我们常规的业务处理中,一般内部处理的接口多数都是以数据库相关的,基于混合式开发的Winform开发框架,虽然在客户端调用的时候,一般选择也是基于Web API的调用,不过后端我们可能不仅仅是针对我们 ...
- 游戏安全有多重要?——GAME-TECH游戏开发者技术沙龙
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由云+社区运营团队发布在腾讯云+社区 腾讯云GAME-TECH沙龙继3月深圳站后,将于4月13日来到北京站,与游戏厂商和游戏开发者,畅聊 ...
- 201621123040《Java程序设计》第九周学习总结
1.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容 泛型部分思维导图 集合部分学习总结 java.util.Collection 是一个集合接口;java.util. ...
- 201621123060《JAVA程序设计》第八周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 源代码: publ ...
- Beta阶段敏捷冲刺报告-DAY4
Beta阶段敏捷冲刺报告-DAY4 Scrum Meeting 敏捷开发日期 2017.11.5 会议时间 11:30 会议地点 羽毛球场 参会人员 全体成员 会议内容 bug的原因讨论, 测试内容安 ...
- djangoueditor 集成xadmin
1.安装Python3兼容版本 https://github.com/twz915/DjangoUeditor3/ 2.model加入字段 from DjangoUeditor.models impo ...
- 20145237 《Java程序设计》第七周学习总结
20145237 <Java程序设计>第七周学习总结 教材学习内容总结 第十三章 一.认识时间与日期 1.时间的度量 在正式认识Java提供了哪些时间处理API之前,得先来了解 ...