1052 最大M子段和

N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M >= N个数中正数的个数,那么输出所有正数的和。
例如:-2 11 -4 13 -5 6 -2,分为2段,11 -4 13一段,6一段,和为26。
Input
第1行:2个数N和M,中间用空格分隔。N为整数的个数,M为划分为多少段。(2 <= N , M <= 5000)
第2 - N+1行:N个整数 (-10^9 <= a[i] <= 10^9)
Output
输出这个最大和
Input示例
7 2
-2
11
-4
13
-5
6
-2
Output示例
26
———————————————————————————————————
1254 最大子段和 V2
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的。当所给的整数均为负数时和为0。
例如:{-2,11,-4,13,-5,-2, 4}将 -4 和 4 交换,{-2,11,4,13,-5,-2, -4},最大子段和为11 + 4 + 13 = 28。
 
Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)
Output
输出交换一次后的最大子段和。
Input示例
7
-2
11
-4
13
-5
-2
4
Output示例
28
——————————————————————————
因为这两道题是一种写法所以我就写在一起
就把连续的一段正负的合在一起得到一段正负相间的序列
然后记录一共有多少个正的记为tot 题目要保留的段数记为 k
那么我们就需要消掉tot-k份 消掉的方法有放弃某一段正的或者是用一段负的把两段正的合并
这样我们维护一个堆 权值是需要付出的代价 这样慢慢合并就能解决问题了
记得记录每一段的相邻段就好辣 当然记得特判边界 我的处理方法是加一段权值为负无穷的段就好辣
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=1e6+1e5+;
const LL inf=1e15;
LL read(){
LL ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,k,f[M],lx[M],rx[M];
LL cnt,sum[M],v,ans;
bool pd(LL x,LL y){return !x||!y||(x>)==(y>);}
LL pabs(LL x){return x>=?x:-x;}
struct node{
LL w,pos;
bool operator <(const node& x)const{return x.w<w;}
};
priority_queue<node>q;
int main(){
n=read(); k=read();
int h=;
while(h<=n&&(v=read())<=) h++;//printf("[%d]\n",h);
if(v>) sum[++cnt]=v;
for(int i=h+;i<=n;i++){
v=read();
if(pd(sum[cnt],v)) sum[cnt]+=v;
else sum[++cnt]=v;
}
if(pd(sum[cnt],-inf)) sum[cnt]+=-inf;
else sum[++cnt]=-inf;
int tot=; for(int i=;i<=cnt;i++)if(sum[i]>=) ans+=sum[i],tot++;
if(tot<=k) return printf("%lld\n",ans),;
int now=tot-k;
for(int i=;i<=cnt;i++) q.push((node){pabs(sum[i]),i}),lx[i]=i-,rx[i]=i+;
lx[]=cnt; rx[cnt]=;
while(now){
node x=q.top(); q.pop();
int k=x.pos;
if(f[k]) continue;
ans-=x.w; now--;
LL l=lx[k],r=rx[k];
f[l]=; f[r]=;
sum[++cnt]=sum[k]+sum[l]+sum[r];
q.push((node){pabs(sum[cnt]),cnt});
lx[cnt]=lx[l]; rx[cnt]=rx[r];
rx[lx[l]]=cnt; lx[rx[r]]=cnt;
}
printf("%lld\n",ans);
return ;
}

1115 最大M子段和 V3

环形最大M子段和,N个整数组成的序列排成一个环,a[1],a[2],a[3],…,a[n](a[n-1], a[n], a[1]也可以算作1段),将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M >= N个数中正数的个数,那么输出所有正数的和。
例如:-2 11 -4 13 -5 6 -1,分为2段,6 -1 -2 11一段,13一段,和为27。
 
Input
第1行:2个数N和M,中间用空格分隔。N为整数的个数,M为划分为多少段。(2 <= N , M <= 100000)
第2 - N+1行:N个整数 (-10^9 <= a[i] <= 10^9)
Output
输出这个最大和
Input示例
7 2
-2
11
-4
13
-5
6
-2
Output示例
26
————————————————————————
这道题不需要特判边界反而更容易QAQ
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstdlib>
#define LL long long
using namespace std;
const int M=;
LL read(){
LL ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
LL lx[M],rx[M],w[M];
LL n,k,tot;
LL cnt=;
LL sum[M],ans;
bool f[M];
struct node{
LL w,pos;
bool operator<(const node &x) const{return w>x.w;}
};
priority_queue<node>q;
LL pd(LL x){return x>=?x:-x;}
bool okay(LL a,LL b){return (a<&&b<)||(a>&&b>)||!a||!b;}
int main()
{
LL v;
n=read(); k=read();
for(int i=;i<=n;i++){
v=read();
if(okay(sum[cnt],v)) sum[cnt]+=v;
else sum[++cnt]=v;
}
if(okay(sum[],sum[cnt])) sum[]=sum[cnt]+sum[],cnt--;
for(int i=;i<=cnt;i++)
if(sum[i]>) ans+=sum[i],tot++;
if(tot<=k){printf("%lld\n",ans); return ;}
LL now=tot-k;
q.push((node){pd(sum[]),});
lx[]=cnt; rx[]=; w[]=pd(sum[]);
q.push((node){pd(sum[cnt]),cnt});
lx[cnt]=cnt-; rx[cnt]=; w[cnt]=pd(sum[cnt]);
for(int i=;i<cnt;i++)
q.push((node){pd(sum[i]),i}),lx[i]=i-,rx[i]=i+,w[i]=pd(sum[i]);
while(now){
node x=q.top(); q.pop();
LL k=x.pos;
if(f[k]) continue;
ans-=w[k]; now--;
LL l=lx[k],r=rx[k];
f[l]=; f[r]=;
cnt++;
sum[cnt]=sum[k]+sum[l]+sum[r];
w[cnt]=pd(sum[cnt]);
q.push((node){w[cnt],cnt});
lx[cnt]=lx[l]; rx[cnt]=rx[r];
rx[lx[l]]=cnt; lx[rx[r]]=cnt;
}
printf("%lld\n",ans);
return ;
}

 

51nod 最大M子段和系列的更多相关文章

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

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

  2. 51nod 最大M子段和系列(1052、1053、1115)

    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 段 ...

  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. FPGA的嵌入式乘法器

    1. FPGA主要应用在并行处理资源的应用,视频与图像处理,无线通信的中频调制解调器. 嵌入式乘法器可以配置成一个 18 × 18 乘法器,或者配置成两个 9 × 9 乘法器.对于那些大于18 × 1 ...

  2. Extjs报错:isField为空或不是对象

             在做Extjs开发的时候,有时候会碰到一个奇怪的问题,就是报错说"isField为空或不是对象",经过调试发现是一个数组,显示的长度是21,但是数组里面的个数只有 ...

  3. How to enable download EXE files from the Sharepoint website

          As we all know,many applications have forbidden to upload and download exe files.Because the e ...

  4. kindeditor 限制上传图片大小及宽高

    进入:/kindeditor/plugins/image/image.js,替换其中的 self.plugin.imageDialog = function (options)方法,代码为: self ...

  5. 更换ubuntu软件源的方法

    第一步:查看本系统Codename 输入lsb_release -a查看本系统Codename,我的codename是bionic,如图: 第二步:搜索与codename对应的镜像地址 我搜索到的是: ...

  6. Manacher算法——最长回文子串

    一.相关介绍 最长回文子串 s="abcd", 最长回文长度为 1,即a或b或c或d s="ababa", 最长回文长度为 5,即ababa s="a ...

  7. PHP+IIS上传大文件

    最近刚接触IIS服务器,在使用php上传大文件的时候,遇到了一些问题.通过查阅网上资料进行了总结,希望对各位有帮助. 第一步,检查PHP的配置. 打开php.ini配置文件 1.file_upload ...

  8. epc笔记

    http://wenku.baidu.com/view/5e921520dd36a32d7375812a.html 1.  先注册, EPC注册EPS业务或non-EPS服务 ?? HSS做什么? 2 ...

  9. 【转】给大家分享一下目前mlc颗粒的内存卡资料

    以下信息是LZ从其它论坛上找到的TF卡也是有讲究的,一分价钱一分货 dboy99 楼主 骚(6) #1楼 2015-8-5 14:49引用Micro SD卡也叫TF卡,作为手机扩展存储空间的唯一方式用 ...

  10. HDU G-免费馅饼

    http://acm.hdu.edu.cn/showproblem.php?pid=1176 Problem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然 ...