题解

这么明显的一个dp,我怎么就没看出来呢?!
首先我们需要一些前提条件:任何划分出来的一个区间的长度不应该超过c。
如果这个区间长度大于c,那么设len=n∗c+klen=n∗c+klen=n*c+k,那么这个区间应该被分成n个长度为c的区间和一个长度为k的区间,因为这样的话去掉的元素数量是相同的,并且区间更小有利于较小的值不易被取到。因为每次去掉的最小值仅仅是局部最小值,不一定是全局最小值。大区间就不一样了,虽然大区间去掉的元素数量相同,但是这些元素会更小一些。
这样的话,我们划分出来的区间应该尽量使得区间的长度为c。
然后我们使用dp来解决剩下的部分:
dp[i]dp[i]dp[i]表示前i个元素组成的集合对应的答案。
状态转移方程:
策略:第i个是否与前c-1个构成一个长为c的区间。
dp[i]=min(dp[i−1]+a[i],dp[i−c+1]+sum[i]−sum[i−c]+min[i−c+1,i])dp[i]=min(dp[i−1]+a[i],dp[i−c+1]+sum[i]−sum[i−c]+min[i−c+1,i])dp[i] = min(dp[i-1]+a[i],dp[i-c+1]+sum[i]-sum[i-c]+min[i-c+1,i])
由于用到了min[i−c+1,i]min[i−c+1,i]min[i-c+1,i]我们还需要维护一个最近cc<script type="math/tex" id="MathJax-Element-339">c</script>个a元素的最小值,方便起见,直接使用multiset即可。

反思

以后遇到这种序列题目,找出一些必要条件之后一定往dp上多想一想。


代码

#include <cstdio>
#include <set>
using namespace std;
typedef long long ll;
const int maxn = 100007;
int a[maxn],n,c;
ll dp[maxn],sum[maxn];
multiset<int> st;
int main(){scanf("%d%d",&n,&c);for(int i = 1;i <= n;++i){scanf("%d",&a[i]);dp[i] = sum[i] = sum[i-1] + a[i];}for(int i = 1;i < c;++i)st.insert(a[i]);for(int i = c;i <= n;++i){st.insert(a[i]);dp[i] = min(dp[i-1] + a[i],dp[i-c] + sum[i] - sum[i-c] - *st.begin());st.erase(st.find(a[i-c+1]));}printf("%lld\n",dp[n]);return 0;
}

codeforces 940E Cashback 有趣的dp相关推荐

  1. codeforces 940E. Cashback(线性dp)

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

  2. Codeforces 940E - Cashback

    940E - Cashback 思路: dp+rmq 可以证明最后划分的区间可以由长度为1和长度为c的区间组成的,这样就可以用O(n)的dp求了,区间最小值随便拿什么维护都可以 状态:dp[i]表示到 ...

  3. [Codeforces 940E]Cashback(dp+set)

    题目链接:http://codeforces.com/problemset/problem/940/E 思路:划分任意长度,每c长度区间可去除一个最小值,所以划分方法就是单独自己一个或者长度为c的区间 ...

  4. CodeForces - 940E Cashback (DP+思维模型)

    题意:给你长度为n的数列,一段序列的价值是,所有数的总和-最小的len/c的数的和,求如何分割数列,使得答案总和最小. 分析:一开始看到向下取整不外乎两种情况:一是用计算机处理,那么表明用暴力,emm ...

  5. Codeforces 940E: Cashback 单调队列优化DP

    传送门 题目描述 给你一个长度为n的数列a和整数c 你需要把它任意分段 每一段假设长度为k,就去掉前 ⌊kc⌋\lfloor\frac{k}{c}\rfloor⌊ck​⌋小的数 最小化剩下的数的和 分 ...

  6. Codeforces 940E Cashback

    Cashback 题意:一共给你N个数, 然后将他们分成连续的子集, 每个集合可以删除 元素个数/c  个最小元素, 然后求每个集合删除元素后的总和. 题解:我们将集合分为1个元素或者K个元素,每K个 ...

  7. [Codeforces 940E]Cashback

    Description 题库链接 给你两个整数 \(n,c\) ,以及一个数列 \(A\) ,让你将序列分为许多段.对于每一段,他的价值为序列内除了最小的 \(\left\lfloor\frac{le ...

  8. CodeForces - 1312E Array Shrinking(区间dp)(通俗易懂)

    CodeForces - 1312E Array Shrinking(区间dp) 题目链接: 没做出来,看了一下别人的题解,才A掉.但网上没发现一篇讲得比较易懂的题解,所以就准备写一篇再加上我自己的理 ...

  9. 【CodeForces 1253C --- Sweets Eating】DP

    [CodeForces 1253C --- Sweets Eating]DP Description Tsumugi brought n delicious sweets to the Light M ...

最新文章

  1. 生成条形码、印章、邮件地址(玩玩)
  2. GoDaddy服务器MySQL配置文件,仅供参考
  3. [以太坊源代码分析]III. 挖矿和共识算法的奥秘
  4. ITK:索引置换序列
  5. 【python数据挖掘课程】十.Pandas、Matplotlib、PCA绘图实用代码补充
  6. linux nacos启动_Nacos集群安装配置
  7. ASP.NET+MVC+使用+Log4net+记录日志笔记
  8. HTML极客自适应网址导航模板,更换背景+看板娘
  9. 每隔一段时间执行php_用php脚本,你如何定时更新商品列表
  10. python限制输入长度_textFiled限制输入长度.
  11. fastjson.JSONObject之对象与JSON转换方法
  12. 伸展树(splay tree)
  13. 使用JSON作为函数的参数(转载)
  14. 从0基础文科生到全国亚军,我的人工智能学习路径
  15. 机器学习中的数学——点估计(三):极大似然估计/最大似然估计(Maximum Likelihood Estimate,MLE)
  16. java 解析GZIP 和 Deflate 网页源文件
  17. egret eui.Scroller 怎么禁止左右或上下滑动
  18. 迅雷7 down.php,迅雷云点播放器(KCPlayer5000)
  19. windows 下查看防火墙状态命令
  20. 菜鸟的Unity自学日志10 音频

热门文章

  1. java pc计数器_java虚拟机-程序计数器PC Register
  2. pe下找不到ssd硬盘_【进入pe系统后认不到硬盘解决方法】进入pe系统看不到硬盘_pe系统不认硬盘...
  3. [C++11]独占的智能指针unique_ptr的删除器
  4. [Java基础]自动装箱和拆箱
  5. Mediator(中介者)--对象行为型模式
  6. HDU - 2444——The Accomodation of Students(判断二分图,二分图最大匹配)
  7. linux加大ram 内核需要,Linux 5.1内核发布:io_uring接口+支持持久性内存用作RAM
  8. Hystrix能解决的问题
  9. 递归算法(二)-分治法
  10. 算法---宝藏最优选择问题