zoukankan      html  css  js  c++  java
  • 环状最大两段子段和

    题目描述

    给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大。

    输入输出格式

    输入格式:

    输入文件maxsum2.in的第一行是一个正整数N,表示了序列的长度。

    第2行包含N个绝对值不大于10000的整数A[i],描述了这段序列,第一个数和第N个数是相邻的。

    输出格式:

    输入文件maxsum2.out仅包括1个整数,为最大的两段子段和是多少。

    输入输出样例

    输入样例#1:
    7
    2 -4 3 -1 2 -4 3
    
    输出样例#1:
    9
    题解:动态规划
    最大两段子段和有两种情况:(x表示子段)
    1.--xxxx--xxxx--
    2.xxx---xxx---xxx
    对于情况1,求出i点右边的最大字段和ti,左边的fi,ans1=max(f[i]+t[i+1])
    对于2,等价于求两段最小子段和,
    求出i点右边的最小字段和ti,左边的fi
    ans2=sum-min(f[i]+t[i+1])
    有一个细节,因为必须有数,所以当f[i]+t[i+1]==sum时,要特判
    
    
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long lol;
     7 lol sum,a[500001],tmp[500001],f[500001],t[500001],maxans,maxx,minx,minans;
     8 int main()
     9 {int n,i,j;
    10     cin>>n;
    11     maxans=-2e18;
    12     for (i=1;i<=n;i++)
    13     {
    14         scanf("%lld",&a[i]);
    15         sum+=a[i];
    16     }
    17     maxx=-2e18;
    18     for (i=1;i<=n;i++)
    19     {
    20         if (tmp[i-1]<0) tmp[i]=a[i];
    21         else tmp[i]=tmp[i-1]+a[i];
    22         if (maxx<tmp[i]) maxx=tmp[i]; 
    23         f[i]=maxx;
    24     }
    25     maxx=-2e18;
    26     for (i=n;i>=1;i--)
    27     {
    28         if (tmp[i+1]<0) tmp[i]=a[i];
    29         else tmp[i]=tmp[i+1]+a[i];
    30         if (maxx<tmp[i]) maxx=tmp[i]; 
    31         t[i]=maxx;
    32     }
    33     for (i=1;i<=n-1;i++)
    34     maxans=max(maxans,f[i]+t[i+1]);
    35     
    36     minx=2e18;
    37     for (i=1;i<=n;i++)
    38     {
    39         if (tmp[i-1]>0) tmp[i]=a[i];
    40         else tmp[i]=tmp[i-1]+a[i];
    41         if (minx>tmp[i]) minx=tmp[i]; 
    42         f[i]=minx;
    43     }
    44     minx=2e18;
    45     for (i=n;i>=1;i--)
    46     {
    47         if (tmp[i+1]>0) tmp[i]=a[i];
    48         else tmp[i]=tmp[i+1]+a[i];
    49         if (minx>tmp[i]) minx=tmp[i]; 
    50         t[i]=minx;
    51     }
    52     minans=2e18;
    53     for (i=1;i<=n-1;i++)
    54     minans=min(minans,f[i]+t[i+1]);
    55     if (sum==minans||maxans>sum-minans)
    56     cout<<maxans<<endl;
    57     else cout<<sum-minans;
    58 }
  • 相关阅读:
    sqlalchemy 转json 的几种常用方式
    程序员的思维模型指南
    软件的本质
    Python数据模型及Pythonic编程
    Linux Kernel C语言编程范式
    U-Boot内存管理
    Linux网络文件系统的实现与调试
    Linux内核内存管理架构
    Linux多核并行编程关键技术
    Go/Python/Erlang编程语言对比分析及示例
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7257586.html
Copyright © 2011-2022 走看看