• 51nod1052

数据量小,可使用O(N*M)的DPAC,递推公式:

dp[i][j]=max(dp[i-1][j-1], dp[i][j-1])+a[j];

dp[i][j]表示前j个数取 i 段的最大子段和,用滚动数组思想优化空间。

  • 51nod1053、51nod1115

进阶版并不使用dp,容易被第一题的思维误导钻到死胡同里。

  1. 可以先做一下处理以便思考,将原序列连续的正数和连续的负数合并,即可得到一个正负交替的序列;
  2. 设新的序列中有k个正数,若m>=k则输出所有正数的和;
  3. 接着考虑m<k的情况,首先所有正数的和(设为S)是我们的初始状态,但因m<k,故我们需要放弃一些正数,或者合并两个相邻的正数(两正数之间的复数也要合并,则相当于额外要一个负数);
  4. 显然我们肯定要放弃那些绝对值更小的正数或附加绝对值更小的负数,这显然是一个贪心问题了;
  5. 既然是以绝对值为标准选数,不妨将所有负数变成正数,然后选出k-m个最小的数来,然后S减去他们就是结果;
  6. 以上可以通过维护一个堆(优先队列)来达到目的,但要处理几个问题;
  7. 每选出一个数,需要将它与其相邻的两个数合并后重新加入堆,而原数要重堆中删除是个麻烦的事情;
  8. 这里可以通过额外的标记处理,所以还需要维护每个数实时的“左邻右舍”,V2需要处理一下边界问题,V3则更简单些;
  9. 代码如下:
#include<iostream>
#include<cstring>
#include<queue>
#define LL long long
using namespace std;
const LL maxn = 1e5+5, INF = 1e9;
int a[maxn], l[maxn], r[maxn];
bool vis[maxn];
LL s[maxn];
priority_queue< pair<LL, int> > q;
int main()
{
//freopen("stdin","r",stdin); int n, m, t;
cin>>n>>m;
int cnt=1;
LL sum=0;
cin>>s[1];
for(int i=2; i<=n; ++i)
{
cin>>t;
if((t>=0) != (s[cnt]>=0)) s[++cnt]=t;
else s[cnt]+=t;
}
//cout<<s[0]<<endl<<s[cnt]<<endl<<endl;
while(s[cnt]*s[1]>=0) s[1]+=s[cnt--];
t=0;
for(int i=1; i<=cnt; ++i)
{
//cout<<s[i]<<endl;
vis[i]=false;
l[i]=i-1;
r[i]=i+1;
if(s[i]>0)
{
sum+=s[i];
s[i]=-s[i];
t++;
}
q.push( make_pair(s[i],i));
}
l[1]=cnt;
r[cnt]=1;
cnt=t;
if(m>=cnt)
{
cout<<sum<<endl;
return 0;
}
while(!q.empty() && cnt>m)
{
pair<LL, int> tmp=q.top();
q.pop();
if(vis[tmp.second])
{
continue;
}
else
{
cnt--;
sum+=s[tmp.second];
s[tmp.second]=s[l[tmp.second]]+s[r[tmp.second]]-s[tmp.second];
q.push( make_pair(s[tmp.second], tmp.second));
vis[l[tmp.second]]=true;
vis[r[tmp.second]]=true;
r[l[l[tmp.second]]]=tmp.second;
l[r[r[tmp.second]]]=tmp.second;
l[tmp.second]=l[l[tmp.second]];
r[tmp.second]=r[r[tmp.second]];
}
}
cout<<max(0ll,sum)<<endl;
return 0;
}

51nod 最大M子段和系列(1052、1053、1115)的更多相关文章

  1. 51nod 最大M子段和系列

    1052 最大M子段和 N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所 ...

  2. 51Nod 最大M子段和系列 V1 V2 V3

    前言 \(HE\)沾\(BJ\)的光成功滚回家里了...这堆最大子段和的题抠了半天,然而各位\(dalao\)们都已经去做概率了...先%为敬. 引流之主:老姚的博客 最大M子段和 V1 思路 最简单 ...

  3. 51Nod 1049 最大子段和

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1049 #include<iostream> #i ...

  4. 51nod 1275 连续子段的差异

    题目看这里 若[i,j]符合要求,那么[i,j]内的任何连续的子段都是符合要求的.我们可以枚举i,找到能合格的最远的j,然后ans+=(j-i+1). 那么问题就转换成了:在固定i的情况下,如何判断j ...

  5. 51Nod 1081:子段求和(前缀和)

    1081 子段求和  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和 ...

  6. 51Nod 1049最大子段和 | 模板

    Input示例 6 -2 11 -4 13 -5 -2 Output示例 20 1.最大子段和模板 #include "bits/stdc++.h" using namespace ...

  7. 51nod 1254 最大子段和 V2 ——单调栈

    N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...

  8. (DP)51NOD 1049 最大子段和

    N个整数组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续子段和的最大值.当所给的整数均为负数时和为0.   例如:-2,11,-4,13,-5 ...

  9. 51nod 1254 最大子段和 V2

    N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...

随机推荐

  1. matplotlib | Python强大的作图工具,让你从此驾驭图表(二)

    今天是数据处理专题的第10篇文章,我们继续来聊聊matplot这个工具库. 在上周的文章当中我们介绍了matplot的基本用法,以及展示了一些简单的例子,让大家直观地了解这个工具包.我们可以简单地将它 ...

  2. Java架构师方案—多数据源开发详解及原理(二)(附完整项目代码)

    1. mybatis下数据源开发工作 2. 数据源与DAO的关系原理模型 3. 为什么要配置SqlSessionTemplate类的bean 4. 多数据源应用测试 1. mybatis下数据源开发工 ...

  3. C#开发PACS医学影像三维重建(一):使用VTK重建3D影像

    VTK简介: VTK是一个开源的免费软件系统,主要用于三维计算机图形学.图像处理和可视化.Vtk是在面向对象原理的基础上设计和实现的,它的内核是用C++构建的. 因为使用C#语言开发,而VTK是C++ ...

  4. 源码分析 Kafka 消息发送流程

    Futuresend(ProducerRecord<K, V> record) Futuresend(ProducerRecord<K, V> record, Callback ...

  5. Ubuntu部署和体验Nexus3

    关于Nexus 如下图,在局域网部署了Nexus之后,可以缓存中央仓库的jar,开发者开发的二方库发布到Nexus上,局域网内的其他人也可以从Nexus下载这些二方库使用: 环境信息 本次实战是在Li ...

  6. P4715 【深基16.例1】淘汰赛

    P4715 [深基16.例1]淘汰赛 题目描述 有 2^n(n≤7) 个国家参加世界杯决赛圈且进入淘汰赛环节.我经知道各个国家的能力值,且都不相等.能力值高的国家和能力值低的国家踢比赛时高者获胜.1 ...

  7. 086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结

    086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结 本文知识点:面向对象基础(类和对象)总结 说明 ...

  8. ReverseFind的用法 ; 查找字符中最后一个字符

    转载:https://blog.csdn.net/frivolousinstant/article/details/52796922 ReverseFind CString::ReverseFind ...

  9. hosts文件的内容

    C:\Windows\System32\drivers\etc\hosts 1 # Copyright (c) 1993-2009 Microsoft Corp. 2 # 3 # This is a ...

  10. 【题解】[SDOI2015]星际战争

    \(\color{red}{Link}\) \(\text{Solution:}\) 观察到,如果一个时间\(T\)可以完成任务,则\(T+1\)这个时间也可以完成任务. 于是我们可以二分. 为了避免 ...