Codeforces 940E Cashback
Cashback
题意:一共给你N个数, 然后将他们分成连续的子集, 每个集合可以删除 元素个数/c 个最小元素, 然后求每个集合删除元素后的总和。
题解:我们将集合分为1个元素或者K个元素,每K个元素查询一下最小值,然后找到最小值, 然后 dp一下就可以找到最后的结果
emmm, 当时CF的时候题意读错了,没有注意到连续,也没有注意到每K个只删除一个(我以为是删除所有的最小元素), 然后 今天补题的时候发现了要连续, WA了一发看了数据, 才发现只删除一个,不是删除全部最小。。。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c)) 10 const int INF = 0x3f3f3f3f; 11 const LL mod = 1e9+7; 12 typedef pair<int,int> pll; 13 const int N = 1e5+10; 14 LL sum[N<<2], Min[N<<2]; 15 LL dp[N], a[N]; 16 void PushUp(int rt){ 17 sum[rt] = sum[rt<<1] + sum[rt<<1|1]; 18 Min[rt] = min(Min[rt<<1], Min[rt<<1|1]); 19 } 20 void Build(int l, int r, int rt){ 21 if(l == r){ 22 sum[rt] = a[l]; 23 Min[rt] = sum[rt]; 24 return ; 25 } 26 int m = l+r >> 1; 27 Build(lson); 28 Build(rson); 29 PushUp(rt); 30 } 31 LL Minn = 0; 32 LL Query(int L, int R, int l, int r, int rt){ 33 if(L <= l && r <= R){ 34 if(Minn > Min[rt]) Minn = Min[rt]; 35 return sum[rt]; 36 } 37 LL ans = 0; 38 int m = l+r >> 1; 39 if(L <= m) ans += Query(L,R,lson); 40 if(m < R) ans += Query(L,R,rson); 41 return ans; 42 } 43 int main(){ 44 int n, c; 45 scanf("%d%d",&n,&c); 46 for(int i = 1; i <= n; i++) scanf("%I64d", &a[i]); 47 Build(1,n,1); 48 for(int i = 1; i <= n; i++){ 49 if(i >= c){ 50 Minn = 1e10; 51 LL tmp = Query(i-c+1,i,1,n,1); 52 dp[i] = min(dp[i-1]+a[i], dp[i-c] + tmp - Minn); 53 } 54 else dp[i] = dp[i-1] + a[i]; 55 } 56 printf("%I64d\n", dp[n]); 57 return 0; 58 }
转载于:https://www.cnblogs.com/MingSD/p/8495104.html
Codeforces 940E Cashback相关推荐
- Codeforces 940E - Cashback
940E - Cashback 思路: dp+rmq 可以证明最后划分的区间可以由长度为1和长度为c的区间组成的,这样就可以用O(n)的dp求了,区间最小值随便拿什么维护都可以 状态:dp[i]表示到 ...
- [Codeforces 940E]Cashback(dp+set)
题目链接:http://codeforces.com/problemset/problem/940/E 思路:划分任意长度,每c长度区间可去除一个最小值,所以划分方法就是单独自己一个或者长度为c的区间 ...
- codeforces 940E Cashback 有趣的dp
题解 这么明显的一个dp,我怎么就没看出来呢?! 首先我们需要一些前提条件:任何划分出来的一个区间的长度不应该超过c. 如果这个区间长度大于c,那么设len=n∗c+klen=n∗c+klen=n*c ...
- [Codeforces 940E]Cashback
Description 题库链接 给你两个整数 \(n,c\) ,以及一个数列 \(A\) ,让你将序列分为许多段.对于每一段,他的价值为序列内除了最小的 \(\left\lfloor\frac{le ...
- CodeForces - 940E Cashback (DP+思维模型)
题意:给你长度为n的数列,一段序列的价值是,所有数的总和-最小的len/c的数的和,求如何分割数列,使得答案总和最小. 分析:一开始看到向下取整不外乎两种情况:一是用计算机处理,那么表明用暴力,emm ...
- codeforces 940E. Cashback(线性dp)
传送门 题意:给出一个nnn个数的序列,要求将序列分成若干段,对于一段长度为kkk的自动删去最小的⌊kc⌋\left \lfloor \frac{k}{c} \right \rfloor⌊ck⌋个数 ...
- Codeforces 940E: Cashback 单调队列优化DP
传送门 题目描述 给你一个长度为n的数列a和整数c 你需要把它任意分段 每一段假设长度为k,就去掉前 ⌊kc⌋\lfloor\frac{k}{c}\rfloor⌊ck⌋小的数 最小化剩下的数的和 分 ...
- Cashback [CodeForces - 940E]
http://codeforces.com/problemset/problem/940/E 题意 将数组a划分成若干段,使每段的f值之和最小,其中f值是区间内元素和减去前k/c(下取整)小的数. 分 ...
- CF 940E Cashback (DP+multiset)
题目链接:http://codeforces.com/problemset/problem/940/E 题意:给一个长度为n的序列a,将它任意分成几个连续子序列,对于一个长度为K的子序列,可以删掉它前 ...
最新文章
- 怎么把快捷键改成eclipse_Java IDE超好用的10个快捷键
- 春节后找工作被面试的经历,好岗位分享给还在找工作中的软件开发爱好者们...
- Matlab读取二进制文件----fread
- php无限极分类实例,PHP实例:PHP无限极分类
- windows安装jenkins及ant/maven/jdk配置
- Java Date 和 Calendar 实例
- pixhawk硬件构架
- JavaSE各阶段练习题----文件和IO
- mysql转sqlserver_mysql转sqlserver工具
- jzoj100046-收集卡片【暴力】
- C语言模拟实现标准库函数之strcmp()
- 画王八java代码参数_java画乌龟源代码-郭遥航.doc
- 单链表的代码python_python版本单链表实现代码
- 人口简史:我们曾经差一点就彻底没了
- 移动应用后端应该使用 AWS 还是 Firebase?
- 蓝桥杯 ADV-98 算法提高 约数个数
- 线性规划 (一) 线性规划的基本形式及各种概念
- 【解析】.NET中代理服务器WebProxy的各种用法
- oracle EM导出AWR报告,AWR报告导出
- java打印堆栈信息_Java 打印堆栈的几种方法
热门文章
- Dracula PRO 零售版
- 用海伦公式计算三角形的面积 python_java程序设计1-2之用海伦公式计算三角形的面积...
- linux期中架构文档,Linux期中架构 - osc_jbr77wuo的个人空间 - OSCHINA - 中文开源技术交流社区...
- 最新《北风网web全栈教程 前端开发全套教程》
- php试卷分析,对试卷分析的必要性与试卷分析的技巧
- 智慧工地解决方案的关键技术
- Java树形结构模糊搜索,模糊匹配
- 【C++】(十五)自定义数据类型——共用体类型、枚举类型
- Java基础练习习题
- RocketMQ 消费者Rebalance 解析——图解、源码级解析