51Nod1053 最大M子段和V2 二分+DP
直接DP的话最多也只能做到\(O(nm)\),对于\(5\times 10^4\)的数据范围实在无能为力
夹克老爷提供的做法是贪心,思想大概是在调整的同时,合理构造每个选择对应的新状态,使得新状态的一些选择可以代表“反悔”当前决策
(然而我没看懂……要是我看懂了也就不会有这个做法了)
其实还有另一种可能更好理解的做法
我们不妨考虑一种类似王钦石二分的思路
可以为每段额外加上一个相同的损失,在之后求最优解时不再考虑段数的限制
不难发现这个损失越大答案的段数就会越少,损失越小段数就会越多,存在单调性
所以我们可以二分这个损失,最后一定能找到一个损失值使得在此前提下存在一种段数满足要求的解
(并不严谨的证明:显然对于一个确定的损失值,最优解的段数是一个区间,然而在损失值+1时得到的最多段数其实就是当前损失值得到的最少段数-1,换句话说这些区间可以覆盖所有可能的段数)
方便起见,可以直接求最优解前提下最少的段数,这样我们只需要找到最少段数\(\le m\)时最小的损失值即可
注意最后求最优解时得到的段数不一定恰好是\(m\),但这种情况其实无所谓,因为出现这种情况时,一定是考虑损失后多加几段最优解不变,所以不用担心
注意二分上下界取\(10^9\)是不够的,但是鉴于题目的特殊性,取所有正数的和一定够了
#include<bits/stdc++.h>
using namespace std;
const int maxn=50005;
int solve(long long);
long long f[maxn],tmp;
int n,m,a[maxn];
int main(){
scanf("%d%d",&n,&m);
int cnt=0;
long long sum=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
cnt+=a[i]>0;
if(a[i]>0)sum+=a[i];
}
if(cnt<=m)printf("%lld",sum);
else{
f[0]=-0x3f3f3f3f3f3f3f3fll;
long long L=-sum,R=sum;
while(L!=R){
long long M=(L+R)>>1;
if(solve(M)<=m)R=M;
else L=M+1;
}
cnt=solve(L);
printf("%lld",tmp+m*L);
}
return 0;
}
int solve(long long M){
long long ans=1ull<<63,mxf=0;
int cnt=0,mxcnt=0,anscnt=0;
for(int i=1;i<=n;i++){
f[i]=max(f[i-1],mxf-M)+a[i];
if(f[i]!=f[i-1]+a[i])cnt=mxcnt+1;
else if(f[i]==mxf-M+a[i])cnt=min(cnt,mxcnt+1);
if(ans<f[i]){
ans=f[i];
anscnt=cnt;
}
else if(ans==f[i])anscnt=min(anscnt,cnt);
if(f[i]>mxf){
mxf=f[i];
mxcnt=cnt;
}
else if(f[i]==mxf)mxcnt=min(mxcnt,cnt);
}
tmp=ans;
return anscnt;
}
51Nod1053 最大M子段和V2 二分+DP的更多相关文章
- 51nod1053 最大M子段和 V2
$n \leq 50000$的序列,问选不超过$m \leq 50000$个区间使得和最大. 如果正数区间总数比$m$小那肯定全选.否则有两种方式减少区间数量:丢掉一个正区间:补一个负区间连接两个正区 ...
- 「学习笔记」wqs二分/dp凸优化
[学习笔记]wqs二分/DP凸优化 从一个经典问题谈起: 有一个长度为 \(n\) 的序列 \(a\),要求找出恰好 \(k\) 个不相交的连续子序列,使得这 \(k\) 个序列的和最大 \(1 \l ...
- 二分+DP HDU 3433 A Task Process
HDU 3433 A Task Process Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- hdu 3433 A Task Process 二分+dp
A Task Process Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- 2018.10.24 NOIP模拟 小 C 的数组(二分+dp)
传送门 考试自己yyyyyy的乱搞的没过大样例二分+dp二分+dp二分+dp过了606060把我自己都吓到了! 这么说来乱搞跟被卡常的正解比只少101010分? 那我考场不打其他暴力想正解血亏啊. 正 ...
- 【bzoj1044】[HAOI2008]木棍分割 二分+dp
题目描述 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且 ...
- Luogu P2511 [HAOI2008]木棍分割 二分+DP
思路:二分+DP 提交:3次 错因:二分写萎了,$cnt$记录段数但没有初始化成$1$,$m$切的次数没有$+1$ 思路: 先二分答案,不提: 然后有个很$naive$的$DP$: 设$f[i][j] ...
- 洛谷$P4322\ [JSOI2016]$最佳团体 二分+$dp$
正解:二分+$dp$ 解题报告: 传送门$QwQ$ 这题长得好套路嗷,,,就一看就看出来是个$01$分数规划+树形$dp$嘛$QwQ$. 考虑现在二分的值为$mid$,若$mid\leq as$,则有 ...
- $bzoj3872\ [Poi2014]\ Ant\ colony$ 二分+$dp$
正解:二分+$dp$ 解题报告: 传送门$QwQ$ 一年过去了依然没有头绪,,,$gql$的$NOIp$必将惨败了$kk$. 考虑倒推,因为知道知道除数和答案,所以可以推出被除数的范围,然后一路推到叶 ...
随机推荐
- JDK源码学习之 集合实现类
一.HashMap (1) 简介:java1.8版本之前HashMap的结构图如下: 数组的每个元素都是一个单链表的头节点,链表是用来解决冲突的,如果不同的key映射到了数组的同一位置处,就将其放入单 ...
- 【BZOJ2082】【POI2010】Divine divisor 假的pollard-rho
题目大意:给你$m$个数$a_i$,定义$n=\Pi_{i=1}^{m}a_i$.将$n$分解质因数为$\Pi p_i^{k_i} $,$p_i$是质数.请输出$2^{max(k_i)}-1$,以及存 ...
- A Node Influence Based Label Propagation Algorithm for Community detection in networks 文章算法实现的疑问
这是我最近看到的一篇论文,思路还是很清晰的,就是改进的LPA算法.改进的地方在两个方面: (1)结合K-shell算法计算量了节点重重要度NI(node importance),标签更新顺序则按照NI ...
- Tomcat发生java.lang.OutOfMemoryError: PermGen space的解决方案
产生该问题的主要原因是JVM永久带空间不足导致的,可以在环境变量CATALINA_OPTS中提高MaxPermSize参数值 set CATALINA_OPTS = -XX:PermSize=12 ...
- 渐进增强与优雅降级 && css3中普通属性和前缀属性的书写顺序
什么是渐进增强与优雅降级? 服务器和浏览器是不同的.当服务器有新版本时,开发人员直接使用新版本的服务器提供服务即可:但是浏览器端,不同的用户使用的浏览器版本不同,型号差异大,我们不可能让用户强制更新 ...
- activity生命周期实例(不同启动模式)
1.生命周期的几个阶段介绍: onCreate: 表示activity被创建,做一些初始化工作如调用setContentView去加载界面布局资源.初始化Acitivity所需数据等. onResta ...
- Java之IO(四)DataInputStream和DataOutputStream
转载请注明源出处:http://www.cnblogs.com/lighten/p/6986155.html 1.前言 DataInputStream和DataOutputStream分别继承了Fil ...
- Javac语法糖之Enum类
枚举类在Javac中是被当作类来看待的. An enum type is implicitly final unless it contains at least one enum constant ...
- 关于注解Annotation第一篇
注解的定义格式如下: public @interface 注解名 {定义体} 定义体就是方法的集合,每个方法实则是声明了一个配置参数.方法的名称作为配置参数的名称,方法的返回值类型就是配置参数的类型. ...
- sql 保留两位小数
select convert(decimal(18,2),1800.2669)