51NOD 1053:最大M子段和 V2——题解

https://www.51nod.com/Challenge/Problem.html#problemId=1053

N个整数组成的序列a1,a2,a3,…,an,将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M >= N个数中正数的个数,那么输出所有正数的和。
例如:-2 11 -4 13 -5 6 -2,分为2段,11 -4 13一段,6一段,和为26。

WQS二分/带权二分裸题,显然函数为凸函数,问题只需要解决没有限制的情况下如何求最大值。

f[i]为到i的最大值,则不取i就是f[i]=f[i-1],取i为f[i]=max{f[k]+sum[i]-sum[k]}-分一段代价。

显然max{f[k]-sum[k]}可以用dp求。

细节还是蛮多的,毕竟你还得记录求出最优值时分段个数,我的做法是限制在可能的情况下取更少的分段数,这样的情况下如果还>m就肯定不符合条件。

#include<queue>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double dl;
const int N=50005;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
int n,m,pcnt,g[N],maxfi[N];
ll s[N],f[N],maxf[N],maxans;
bool pan(ll c){
    for(int i=1;i<=n;i++){
        if(f[i-1]<maxf[i-1]+s[i]-c){
            f[i]=maxf[i-1]+s[i]-c;
            g[i]=g[maxfi[i-1]]+1;
        }else{
            f[i]=f[i-1];
            g[i]=g[i-1];
        }
        if(maxf[i-1]<f[i]-s[i]){
            maxf[i]=f[i]-s[i];
            maxfi[i]=i;
        }
        else{
            maxf[i]=maxf[i-1];
            maxfi[i]=maxfi[i-1];
            if(maxf[i-1]==f[i]-s[i]){
                if(g[i]>g[maxfi[i-1]]) maxfi[i]=maxfi[i-1];
                else maxfi[i]=i;
            }
        }
    }
    return g[n]<=m;
}
ll solve(ll l,ll r){
    ll b;
    while(l<r){
        ll mid=(l+r)>>1;
        if(!pan(mid))l=mid+1;
        else{
            b=f[n];r=mid;
        }
    }
    return l*m+b;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++){
        ll a=read();
        if(a>0){
            ++pcnt;maxans+=a;
        }
        s[i]=s[i-1]+a;
    }
    if(pcnt<=m) printf("%lld\n",maxans);
    else printf("%lld\n",solve(0,1e9));
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +

+++++++++++++++++++++++++++++++++++++++++++

 

 

posted @ 2021-07-07 16:42  luyouqi233  阅读(71)  评论(0编辑  收藏  举报