51Nod 1052/1053/1115 最大M子段和V1/V2/V3
2018-02-21 00:06
597 查看
V1
N个整数组成的序列a[1],a[2],a[3],…,a
,将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M
>= N个数中正数的个数,那么输出所有正数的和。N,M<=5000
例如:-2 11 -4 13 -5 6 -2,分为2段,11
-4 13一段,6一段,和为26。
V2
N个整数组成的序列a[1],a[2],a[3],…,a
,将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M >= N个数中正数的个数,那么输出所有正数的和。 N,M<=50000
例如:-2 11 -4 13 -5 6 -2,分为2段,11 -4 13一段,6一段,和为26。
V3
环形最大M子段和,N个整数组成的序列排成一个环,a[1],a[2],a[3],…,a
( a
, a[1]也可以算作1段),将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M>=N个数中正数的个数,那么输出所有正数的和。N,M<=100000
例如:-2 11 -4 13 -5 6 -1,分为2段,6 -1 -2 11一段,13一段,和为27。
这三道题非常类似可以用几乎同一个code过掉
我们直接先考虑V3比较好做
首先将所有连续且符号相同的数加在一起,那么我们得到一个正负交替的环
如果不考虑限制,显然取所有正数最优
现在考虑限制,我们假设环上正数c个
那么就要减少M-c段,考虑减少段数的手段
1.删去一段
2.将两端合并成为一段
这个时候发现问题可以转化为经典的种花问题:
将所有的正数变为负数,在N个数(全部为负)中选出M-c个最大的,而相邻的不能选
选出来的数加上原本所有正数的和就是答案
直接套用原来的可撤销贪心做法就可以了,v2就多加一个权值为-∞的0号节点即可
V2code
V3code
N个整数组成的序列a[1],a[2],a[3],…,a
,将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M
>= N个数中正数的个数,那么输出所有正数的和。N,M<=5000
例如:-2 11 -4 13 -5 6 -2,分为2段,11
-4 13一段,6一段,和为26。
V2
N个整数组成的序列a[1],a[2],a[3],…,a
,将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M >= N个数中正数的个数,那么输出所有正数的和。 N,M<=50000
例如:-2 11 -4 13 -5 6 -2,分为2段,11 -4 13一段,6一段,和为26。
V3
环形最大M子段和,N个整数组成的序列排成一个环,a[1],a[2],a[3],…,a
( a
, a[1]也可以算作1段),将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M>=N个数中正数的个数,那么输出所有正数的和。N,M<=100000
例如:-2 11 -4 13 -5 6 -1,分为2段,6 -1 -2 11一段,13一段,和为27。
这三道题非常类似可以用几乎同一个code过掉
我们直接先考虑V3比较好做
首先将所有连续且符号相同的数加在一起,那么我们得到一个正负交替的环
如果不考虑限制,显然取所有正数最优
现在考虑限制,我们假设环上正数c个
那么就要减少M-c段,考虑减少段数的手段
1.删去一段
2.将两端合并成为一段
这个时候发现问题可以转化为经典的种花问题:
将所有的正数变为负数,在N个数(全部为负)中选出M-c个最大的,而相邻的不能选
选出来的数加上原本所有正数的和就是答案
直接套用原来的可撤销贪心做法就可以了,v2就多加一个权值为-∞的0号节点即可
V2code
#pragma GCC opitmize("O3") #pragma G++ opitmize("O3") #include<queue> #include<stdio.h> #include<string.h> #include<algorithm> #define N 50010 using namespace std; int n,m,t=0,l[N],r[N]; long long S=0,s[N],v[N]; priority_queue<pair<long long,int> > q; bool vis[N]={0}; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i){ scanf("%lld",v+i); if(!t && v[i]<0) continue; else if(!t || (v[i]>=0)!=(s[t]>=0)) s[++t]=v[i]; else s[t]+=v[i]; } while(s[t]<0) s[t--]=0; for(int i=1;i<=t;++i){ l[i]=i-1; r[i]=i+1; if(i&1){ S+=s[i]; s[i]=-s[i]; q.push(make_pair(s[i],i)); } else q.push(make_pair(s[i],i)); } r[t]=0; l[0]=t; r[0]=1; q.push(make_pair(s[0]=-1000000000000ll,0)); if(m>(t>>1)) return 0&printf("%lld\n",S); pair<long long,int> x; int y; for(m=(t-(t>>1))-m;m--;){ x=q.top(); q.pop(); if(vis[y=x.second]){++m; continue;} else{ S+=s[y]; s[y]=-s[y]+s[l[y]]+s[r[y]]; q.push(make_pair(s[y],y)); r[l[l[y]]]=y; l[r[r[y]]]=y; vis[l[y]]=1; vis[r[y]]=1; l[y]=l[l[y]]; r[y]=r[r[y]]; } } printf("%lld\n",max(0ll,S)); }
V3code
#pragma GCC opitmize("O3") #pragma G++ opitmize("O3") #include<queue> #include<stdio.h> #include<string.h> #include<algorithm> #define N 200010 using namespace std; int n,m,t=0,l[N],r[N],c; long long S=0,s[N],v[N]; priority_queue<pair<long long,int> > q; bool vis[N]={0}; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i){ scanf("%lld",v+i); if(!t || (v[i]>=0)!=(s[t]>=0)) s[++t]=v[i]; else s[t]+=v[i]; } if((s[1]>=0)==(s[t]>=0)) s[1]+=s[t--]; for(int i=1;i<=t;++i){ l[i]=i-1; r[i]=i+1; if(s[i]>=0){ S+=s[i]; s[i]=-s[i]; c++; q.push(make_pair(s[i],i)); } else q.push(make_pair(s[i],i)); } r[t]=1; l[1]=t; if(m>=c) return 0&printf("%lld\n",S); pair<long long,int> x; int y; for(m=c-m;m--;){ x=q.top(); q.pop(); if(vis[y=x.second]){++m; continue;} else{ S+=s[y]; s[y]=-s[y]+s[l[y]]+s[r[y]]; q.push(make_pair(s[y],y)); r[l[l[y]]]=y; l[r[r[y]]]=y; vis[l[y]]=1; vis[r[y]]=1; l[y]=l[l[y]]; r[y]=r[r[y]]; } } printf("%lld\n",max(0ll,S)); }
相关文章推荐
- 51nod 最大M子段和 V1,V2,V3 dp 贪心 heap(bzoj2288)
- 51Nod-1053-最大M子段和 V2
- 【贪心+优先队列】51Nod 1053 最大M子段和 V2
- 51nod 1053 最大M子段和 V2
- 51nod 1115 最大M子段和 V3 (链表)
- 51nod 1053 最大M子段和 V2 (链表 对经典dp进行优化)
- 51nod 1254最大子段和V2
- 51nod 最大M子段和V2【贪心】【链表】【堆】
- 51Nod-1254-最大子段和 V2
- 51nod 1052[最大子段和]【DP】
- 51nod 1052 最大m子段和 DP
- 51nod 1053 最大M子段和 V2
- 51nod 1052最大M子段和 & poj 2479最大两子段和
- 51nod 1052 最大M子段和
- 51nod 1254 最大子段和 V2 ——单调栈
- 51nod 1052 最大M子段和 (区间dp)
- 51nod 1053 最大M子段和 V2[贪心][链表][堆]
- 51Nod 1052 最大M子段和
- 51nod 1049 最大子段和
- 51Nod 1051 最大子矩阵和 (最大子段和变形)