zoukankan      html  css  js  c++  java
  • 51nod 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。
     

    输入

    第1行:2个数N和M,中间用空格分隔。N为整数的个数,M为划分为多少段。(2 <= N , M <= 100000)
    第2 - N+1行:N个整数 (-10^9 <= a[i] <= 10^9)

    输出

    输出这个最大和

    输入样例

    7 2
    -2
    11
    -4
    13
    -5
    6
    -2

    输出样例

    26

    相比v2,改成首尾相接的,如果首尾同号就归并。
    代码:
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <set>
    using namespace std;
    typedef long long ll;
    int n,m;
    ll d,last;
    ll s[100005];
    int l[100005],r[100005];
    int sc;
    void modify(int cur) {///修改左右相邻结点的下标
        int ll = l[cur],rr = r[cur];
        r[ll] = rr;
        l[rr] = ll;
    }
    int main() {
        while(~scanf("%d%d",&n,&m)) {
            sc = last = 0;
            ll sum = 0,ans = 0,c = 0;
            set<pair<ll,int> > ss;
            for(int i = 0;i < n;i ++) {
                scanf("%lld",&d);
                if(d * last < 0) {
                    s[++ sc] = sum;
                    sum = d;
                }
                else sum += d;
                last = d;
            }
            if(sum) s[++ sc] = sum;
            if(s[1] > 0 && s[sc] > 0 || s[1] < 0 && s[sc] < 0) {
                s[1] += s[sc --];
            }
            for(int i = 1;i <= sc;i ++) {
                ss.insert(make_pair(abs(s[i]),i));
                c += s[i] > 0;
                ans += (s[i] > 0 ? s[i] : 0);
                l[i] = i - 1;
                r[i] = i + 1;
            }
            r[sc] = 1;
            l[1] = sc;
            while(c > m) {
                int cur = ss.begin() -> second;
                ss.erase(ss.begin());
                ans -= abs(s[cur]);
                s[cur] += s[l[cur]] + s[r[cur]];
                ss.erase(make_pair(abs(s[l[cur]]),l[cur]));
                modify(l[cur]);
                ss.erase(make_pair(abs(s[r[cur]]),r[cur]));
                modify(r[cur]);
                if(s[cur]) ss.insert(make_pair(abs(s[cur]),cur));
                c --;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    #研发解决方案#研发协作平台CloudEngine
    人生做出的选择越多,友谊的小船翻得越快?
    告诉别人你是谁:边界的那些事儿
    如何从零开始搭建一个技术平台?
    Windows10 自动配置切换IP地址
    Human disease database
    R语言install.packages("jpeg")报错
    RStudio中,出现中文乱码问题的解决方案(修改文件编码)
    How do I run Adobe Flash on Chrome?
    RGB颜色查询对照表
  • 原文地址:https://www.cnblogs.com/8023spz/p/10912467.html
Copyright © 2011-2022 走看看