zoukankan      html  css  js  c++  java
  • C++学习(1):最大子段和(多种解法)

    问题:给定由n个数(可能为负数)组成的序列a1,a2,a3,...,an,求该序列子段和的最大值。

    第一种解法:(最容易考虑的方法,将所有的子段一一相加,然后比较)

     1 #include<iostream>
     2 using namespace std;
     3 int Maxsum(int n,int *a,int &besti,int &bestj)
     4 {
     5     int sum = 0;
     6     for(int i=1;i<=n;i++)
     7     {
     8         int thissum = 0;
     9         for(int j=i;j<=n;j++)
    10         {
    11             thissum +=a[j];
    12             if(thissum>sum)
    13             {
    14                 sum = thissum;
    15                 besti = i;
    16                 bestj = j;
    17             }
    18         }
    19     }
    20     return sum;
    21 }
    22 
    23 int main()
    24 {
    25     int Case = 1;
    26     int T;//共有多少组数
    27     cin>>T;
    28     while(T>0)
    29     {
    30         T--;
    31         int sum;
    32         int N = 9;//一组有多少个数据
    33         cin>>N;
    34         int* array = new int[N+1];
    35         for(int i=1;i<=N;i++)
    36         {
    37             cin>>array[i];
    38         }
    39         int besti,bestj;
    40         sum = Maxsum(N,array,besti,bestj);
    41         cout<<"Case "<<Case<<":"<<endl;
    42         cout<<sum<<" "<<besti<<" "<<bestj<<endl;
    43 
    44         if(T>0)
    45         {
    46             cout<<endl;
    47         }
    48         Case++;
    49     }
    50     return 0;
    51 }

     第二种解法:(利用分治算法,将序列从中间分为两个部分a[1:n/2]和a[n2+1:n],分别求最大子段和,然后比较。)

      1 #include<iostream>
      2 using namespace std;
      3 int MaxSubSum(int *a,int left,int right,int &besti,int &bestj)
      4 {
      5     int sum = 0;
      6     if(left==right)
      7     {
      8         sum = a[left];
      9         besti  = bestj = left;
     10     }
     11     else
     12     {
     13         int center = (left+right)/2;
     14         int leftsum = MaxSubSum(a,left,center,besti,bestj);
     15         int rightsum = MaxSubSum(a,center+1,right,besti,bestj);
     16 
     17         int s1 = -10001;
     18         int lefts = 0;
     19         for(int i = center;i>=left;i--)
     20         {
     21             lefts +=a[i];
     22             if(lefts>=s1)
     23             {
     24                 s1 = lefts;
     25                 besti = i;
     26                 
     27             }
     28         }
     29 
     30         int s2 = -10001;
     31         int rights = 0;
     32         for(int j = center+1;j<=right;j++)
     33         {
     34             rights +=a[j];
     35             if(rights>s2)
     36             {
     37                 s2 = rights;
     38                 bestj = j;
     39             }
     40         }
     41 
     42         sum = s1+s2;
     43 
     44         if(sum<leftsum)
     45         {
     46             sum = MaxSubSum(a,left,center,besti,bestj);
     47         }
     48         if(sum<rightsum)
     49         { 
     50             sum = MaxSubSum(a,center+1,right,besti,bestj);
     51         }
     52     }
     53     return sum;
     54 }
     55 
     56 int MaxSum(int n,int *a,int &besti,int &bestj)
     57 {
     58     return MaxSubSum(a,1,n,besti,bestj);
     59 }
     60 
     61 int main()
     62 {
     63     int Case = 1;
     64     int T;//共有多少组数
     65     cin>>T;
     66     while(T>0)
     67     {
     68         bool flag = true;
     69         T--;
     70         int sum;
     71         int N;//一组有多少个数据
     72         cin>>N;
     73         int* array = new int[N+1];
     74         for(int i=1;i<=N;i++)
     75         {
     76             cin>>array[i];
     77         }
     78         int besti,bestj;
     79         //判断是否全部为负数
     80         for(int j = 1;j<=N;j++)
     81         {
     82             if(array[j]>0) flag = false;
     83         }
     84         if(!flag)
     85         {
     86             sum = MaxSum(N,array,besti,bestj);
     87             cout<<"Case "<<Case<<":"<<endl;
     88             cout<<sum<<" "<<besti<<" "<<bestj<<endl;
     89         }else
     90         {
     91             sum = array[1];
     92             besti = bestj = 1;
     93             cout<<"Case "<<Case<<":"<<endl;
     94             cout<<sum<<" "<<besti<<" "<<bestj<<endl;
     95         }
     96         
     97         if(T>0)
     98         {
     99             cout<<endl;
    100         }
    101         Case++;
    102     }
    103     return 0;
    104 }
  • 相关阅读:
    i春秋 可恶的黑客
    bugku 变量1
    开源Odoo ERP 13.2版本发行说明(译文+原文)
    Java数学运算
    SET DYNAMICS 365 COLORS AND LOGO USING THEMES
    Use SQL to Query Data from CDS and Dynamics 365 CE
    SAP四代增强实现:VA01销售订单复制项目文本时不需要显示文本框和回车
    ABAP 动态备份自建表数据到新表(自建表有数据的情况下要改字段长度或者其他)
    NTFS ADS(备用数据流)
    Windows RestartManeger重启管理器
  • 原文地址:https://www.cnblogs.com/xcxfuryit/p/7363165.html
Copyright © 2011-2022 走看看