zoukankan      html  css  js  c++  java
  • 动态规划[入门]2-循环数组最大子段和

    分析:
    (1)笨方法,我们可以用普通最大子段和的方法解决这个问题。我们从每个位置“断开”环,然后按普通的最大子段和的方法去做。这样做的复杂度是O(n^2)。
    (2)巧妙点的方法,我们之所以要从某个位置切开是因为循环的最大子段和可能是跨越一部分头和尾。


    如上图,最优解可能是0..i, j + 1.. n – 1两段,那这时,其实中间i + 1..j是个“最小子段和”,因为总和是一定得嘛。

    所以“循环数组得最大子段和”问题,可以把环从任意位置断开,然后求出最优解 = max(普通的最大子段和, 总和 – 普通的“最小子段和”)

    求最小子段和,显然也可以用最大子段和的方法求一次就可以了。所以循环数组的最大子段和,实际上是求了两次最大子段和而已。
     
    最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。
     
    输入

    第1行:整数序列的长度N(2 <= N <= 50000)
    第2 - N+1行:N个整数 (-10^9 <= S[i] <= 10^9)
    输出
     
    输出循环数组的最大子段和。
     
    输入示例

    6
    -2
    11
    -4
    13
    -5
    -2

    输出示例

    20
     
    请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。
    不同语言如何处理输入输出,请查看下面的语言说明。
     1 #include<cstdio>
     2 long long max(long long a,long long b){
     3     if (a>b) return a;
     4     else return b;
     5 }
     6 long long min(long long a,long long b){
     7     if (a<b) return a;
     8     else return b;
     9 }
    10 int main(){
    11     int n;
    12     long long last,ans,tot,min_ans;
    13     int s[50000];
    14     scanf("%d",&n);
    15     tot=0;
    16     for (int i=0;i<n;i++){
    17         scanf("%d",&s[i]);
    18         tot+=s[i];
    19     }
    20     last=-100000000LL;
    21     ans=-100000000LL;
    22     for(int i=0;i<n;i++){
    23         last=max(last,0)+s[i];
    24         ans=max(last,ans);
    25     }
    26     last=100000000LL;
    27     min_ans=100000000LL;
    28     for(int i=0;i<n;i++){
    29         last=min(last,0)+s[i];
    30         min_ans=min(last,min_ans);
    31     }
    32     
    33     printf("%d",max(ans,tot-min_ans));
    34     
    35 }

    Int32溢出,悲剧!!c++不熟啊!!

    上python:

     1 n=int(input())
     2 s=[]
     3 last=-10000000000
     4 ans=-10000000000
     5 tot=0
     6 min_last=10000000000
     7 min_ans=10000000000
     8 for i in range(n):
     9     s.append(int(input()))
    10     tot+=s[i]
    11     last=max(last,0)+s[i]
    12     ans=max(last,ans)
    13     min_last=min(min_last,0)+s[i]
    14     min_ans=min(min_ans,min_last)
    15 print(max(ans,tot-min_ans))    
    16     
    17     
    18     
  • 相关阅读:
    Mac OS X上安装 Ruby运行环境
    MAC 命令行工具(Command Line Tools)安装
    如何快速正确的安装 Ruby, Rails 运行环境
    安裝 Rails 開發環境
    用模块化编程
    阅读技术书籍
    NHibernate构建一个ASP.NET MVC应用程序
    SQL注入
    Redis
    Code digest
  • 原文地址:https://www.cnblogs.com/nbalive2001/p/4870838.html
Copyright © 2011-2022 走看看