cf 940E Cashback
考场上能想出这道题挺爽得,还剩4分钟的时候A了,copyhls 的B的代码只改了一点点变量头文件和return 0竟然没被判重,结果是long long+=int*int,后面的会变成负数的问题。
思考过程:
看到数据范围是1e5 要么nlogn要么On,nlogn一般是dp+二分维护/线段树等数据结构维护,On一般是贪心或者dp(单调队列,单调栈优化)
首先想贪心的想法,这题就是要找一种划分方式使得能删去的数字的总和最大,那么我们观察第二个样例想到如果把一大堆大的数字放在一起的话,就可以删掉一些比较大的数字,因为他删除的是这个划分区间中最小的几个数字,所以最好是把较大的数字放在一个区间里。
然而贪心好像还是不知道怎么去划分,接着我们想,既然是删掉k/c个,那么k<c是不删除的无意义,k=c删除1个,c<=k<2c还是删除1个,那么相当于第c+1个到第k个放在上一区间是无意义的。证明:假如前c个的最小值是mini ,如果a[c+1]<mini,那么删掉的就是a[c+1],不值得,如果a[c+1]>=mini,那么删除的还是mini,吧c+1个划分到上个区间也是无意义的。
但如果长度为2c的话就能删除2个,但一定不如化成2个c长度的区间优秀。假如前c个的最小值是mini1,次小值是mini2,后c个的最小值是mini3,假如mini2<mini3,那么删除mini1+mini3>mini1+mini2,划分成2段更好,如果mini2>=mini3,那么删除的还是mini1+mini3,是等价的。
这样我们就能想到dp了,f[i]为到i位置能减去的最大的和是多少,可以从f[i-1]转移过来,就相当于把i分到一个长度不到c的区间里,无法减去值,也可以从f[i-c]转移过来,说明吧i-c+1到i分成一个长度为c的区间,然后删掉里面的最小值,用单调队列维护最小值即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxl 100010using namespace std;int n,c,l,r;
int a[maxl],num[maxl],ind[maxl];
long long f[maxl];
long long sum=0;int main()
{scanf("%d%d",&n,&c);for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum+=a[i];l=1;r=0;int pre;for(int i=1;i<=n;i++){while(num[r]>a[i] && r>0)r--;ind[++r]=i;num[r]=a[i];if(r<l)l=r;pre=max(0,i-c);if(ind[l]<=pre)l++;if(pre==i-c)f[i]=max(f[pre]+num[l],f[i-1]);elsef[i]=f[i-1];}printf("%I64d",sum-f[n]);return 0;
}
cf 940E Cashback相关推荐
- CF 940E Cashback (DP+multiset)
题目链接:http://codeforces.com/problemset/problem/940/E 题意:给一个长度为n的序列a,将它任意分成几个连续子序列,对于一个长度为K的子序列,可以删掉它前 ...
- Codeforces 940E - Cashback
940E - Cashback 思路: dp+rmq 可以证明最后划分的区间可以由长度为1和长度为c的区间组成的,这样就可以用O(n)的dp求了,区间最小值随便拿什么维护都可以 状态:dp[i]表示到 ...
- Codeforces 940E Cashback
Cashback 题意:一共给你N个数, 然后将他们分成连续的子集, 每个集合可以删除 元素个数/c 个最小元素, 然后求每个集合删除元素后的总和. 题解:我们将集合分为1个元素或者K个元素,每K个 ...
- codeforces 940E Cashback 有趣的dp
题解 这么明显的一个dp,我怎么就没看出来呢?! 首先我们需要一些前提条件:任何划分出来的一个区间的长度不应该超过c. 如果这个区间长度大于c,那么设len=n∗c+klen=n∗c+klen=n*c ...
- [Codeforces 940E]Cashback(dp+set)
题目链接:http://codeforces.com/problemset/problem/940/E 思路:划分任意长度,每c长度区间可去除一个最小值,所以划分方法就是单独自己一个或者长度为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⌋小的数 最小化剩下的数的和 分 ...
最新文章
- bzoj 1691: [Usaco2007 Dec]挑剔的美食家
- oracle database firewall 配置 保护 db,Oracle DB control配置启动
- “玩转课堂”软件需求规格说明
- awx文件解析_Android so(ELF)文件解析
- CONFIGURE CONTROLFILE AUTOBACKUP ON/OFF;
- 仿花生小说蓝色小说网站导航网站源码
- 判断用户是否已经登录
- 移动设备 计算机设备,移动设备
- 在 Visual Studio 2010 中配置SharpPcap
- 30种EMC标准电路
- 手撕包菜磁力搜索引擎的开源说明
- flash读取程序 msp430_MSP430 flash的操作
- 计算机应用一些常用技巧
- 白嫖JetBrains全家桶第二波与第三波
- 几次推广都没能火起来,腾讯直接把微视嵌入朋友圈了?
- linux mv命令例子,linux命令mv
- SendMessage函数完全使用手册 (解读WM_)
- 通过单片机定时器输出周期为1s的方波,驱动LED灯闪烁
- 行列式的子式、主子式、顺序主子式、余子式、代数余子式
- MySQL索引基础续