最大连续和【总结】

最大连续和的总结

1. O(n^3)的暴力枚举

/*
思路:暴力枚举每个小区间。
/*
#include
using namespace std;
const int maxn = 1e5+10; 
int a[maxn];
int main(void){
 int n;
 cin>>n;
 for(int i = 1; i <= n; i++){
     cin>>a[i];
 }
 int ans = a[1];
 int ans1 = 0;
 int ans2 = 0;
 for(int i = 1; i <= n; i++){
     for(int j = i; j <= n; j++){
         int sum = 0;
         for(int k = i; k <= j; k++){
             sum += a[k];
         }
         if(sum > ans){
             ans = sum;
             ans1 = i;
             ans2 = j;
         }
     }
 }
 cout<

2. O(n^2)暴力枚举

  1. 简单枚举

    #include
    using namespace std;
    const int maxn = 1e5+10; 
    int a[maxn];
    int main(void){
      int n;
      cin>>n;
      for(int i = 1; i <= n; i++){
          cin>>a[i];
      }
      int ans = a[1];
      int ans1 = 0;
      int ans2 = 0;
      int i,j;
      for(i = 1; i <= n; i++){       //只是对O(n^3)的一个简单优化
          int sum = 0;
          for(j = i; j <= n; j++){
              sum += a[j];
              if(sum > ans){
                  ans = sum;
                  ans1 = i;
                  ans2 = j;
              }
          }
      }
      cout<
  2. 预处理前缀和

    /*
    思路:连续子序列之和等于两个前缀和之差。
    */
    #include
    using namespace std;
    const int maxn = 1e5+10; 
    int a[maxn];
    int s[maxn];
    int main(void){
      int n;
      cin>>n;
      s[0] = 0;
      for(int i = 1; i <= n; i++){
          cin>>a[i];
          s[i] = s[i-1]+a[i];
      }
      int ans = a[1];
      int ans1 = 0;
      int ans2 = 0;
      for(int i = 1; i <= n; i++){
          for(int j = i; j <= n; j++){
              int temp = s[j]-s[i-1];
              if(temp>ans){
                  ans = temp;
                  ans1 = i;
                  ans2 = j;
              }
          }
      }
      cout<

3. O(nlogn)分治法求解


#include
using namespace std;
const int maxn = 1e5+10;
int s[maxn];
int maxsub(int a,int b){      //尤其注意,设计的是左闭右开的区间格式 
 if(b-a==1) 
        return s[a];      //如果只包含一个数则直接返回 
 int mid = a+(b-a)/2;
 int max1 = max(maxsub(a,mid),maxsub(mid,b));      //递归得到左右两边串最大值 
 int L = s[mid-1], sum = 0;
    for(int i = mid-1; i >= a; i--)        //从中间出发往左边最大连续和 
    {
     sum += s[i];
     L = max(L,sum);
 }
 int R = s[mid];
 sum = 0;
 for(int i = mid; i < b; i++)      //从中间出发往右边最大连续和 
 {
     sum += s[i];
     R = max(R,sum);
 }
 return max(max1,L+R);   //L+R则表示起终点分别在两端的最大连续和 
} 
 
int main(void)
{
 int n;
 while(cin>>n)
 {
     for(int i = 0; i < n; i++)
         cin>>s[i];
     cout<

4. O(n)在线处理

#include
using namespace std;
int main(void){
 int t;
 cin>>t;
 for(int i = 1; i <= t; i++){
     int n;
     cin>>n;
     int maxx = -1001;
     int sum = -1001;
     int pos1 = 1;
     int pos2 = 1;
     int ans1 = 1;
     int ans2 = 1; 
     for(int j = 1; j <= n; j++){
         int x;
         cin>>x;
         if(sum+x>x){    
             sum += x;
             pos2++;
         }
         else{
             sum = x;
             pos1 = j;
             pos2 = j;
         }
         if(sum>maxx){
             maxx = sum;
             ans1 = pos1;
             ans2 = pos2;
         }
     }
     printf("Case %d:\n",i);
        printf("%d %d %d\n",maxx,ans1,ans2);
        if(i!=t)
            printf("\n");
 }
 return 0;
}

你可能感兴趣的:(最大连续和【总结】)