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$. 考虑倒推,因为知道知道除数和答案,所以可以推出被除数的范围,然后一路推到叶 ...
随机推荐
- 关于Boolean()
Boolean(value); 如果省略 value 参数,或者设置为 0.-0.null."".false.undefined 或 NaN,则该对象设置为 false. 否则设置 ...
- Apache Log4j配置说明
1.Log4j简介 Log4j是Apache的一个开源项目,它允许开发者以任意间隔输出日志信息.Log4j主要由三大类组件构成: 1)Logger-负责输出日志信息,并能够对日志信息进行分类筛选,即决 ...
- (4)Oracle基础--操作表中数据
· 添加数据 <1> INSERT 语句 ① 向表中所有字段添加值 语法: INSERT INTO table_name (column1,column2...) VALUES(val ...
- 基于SWOOLE的分布式SOCKET消息服务器架构
消息服务器使用socket,为避免服务器过载,单台只允许500个socket连接,当一台不够的时候,扩充消息服务器是必然,问题来了,如何让链接在不同消息服务器上的用户可以实现消息发送呢? 要实现消息互 ...
- 剑指offer五十七之二叉树的下一个结点
一.题目 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 二.思路 结合图,我们可发现分成两大类: 1.有右子树 ...
- Linux驱动:SPI驱动编写要点
题外话:面对成功和失败,一个人有没有“冠军之心”,直接影响他的表现. 几周前剖析了Linux SPI 驱动框架,算是明白个所以然,对于这么一个庞大的框架,并不是每一行代码都要自己去敲,因为前人已经把这 ...
- 【转】asp.net mvc(模式)和三层架构(BLL、DAL、Model)的联系与区别
原文地址:http://blog.csdn.net/luoyeyu1989/article/details/8275866 首先,MVC和三层架构,是不一样的. 三层架构中,DAL(数据访问层).BL ...
- ES6 箭头函数 this 指向
ES6 箭头函数 this 指向 箭头函数有几个使用注意点: 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象. 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个 ...
- c# static用法
有时候写程序时常常遇到这样的情况: 1.定义了变量和方法不知道什么时候该加上static修饰符. 2.static变量和方法与非static变量和方法有什么区别? 3.在一个类的静态方法里为什么不 ...
- leetcode--539. Minimum Time Difference
Given a list of -hour clock time points in "Hour:Minutes" format, find the minimum minutes ...