zoukankan      html  css  js  c++  java
  • 经典算法问题

    维基百科:在计算机科学中,最大子数列问题的目标是在数列的一维方向找到一个连续的子数列,使该子数列的和最大。例如,对一个数列 −2, 1, −3, 4, −1, 2, 1, −5, 4,其连续子数列中和最大的是 4, −1, 2, 1, 其和为6。

    时间复杂度:O(N^3)

    最粗鲁的做法就是直接三重循环,起点i,终点j,k是从i到j

    代码如下:

    #include <bits/stdc++.h>
    
    using namespace std;
                          
    int main()
    {
        int n;
        cin>>n;
        int a[n];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        int ans=a[0];
         for(int i=0;i<n;i++){
             for(int j=0;j<n;j++){
                 int s=0;
                 for(int k=i;k<=j;k++){
                  s+=a[k];     
                 }ans=max(ans,s);
             }
         }cout<<ans;
        return 0;
    }

    时间复杂度:O(N^2)

    将上述代码稍微优化一下(空间换时间)

    #include <bits/stdc++.h>
    
    using namespace std;
                          
    int main()
    {
        int n;
        cin>>n;
        int a[n],sum[n];//sum[i]表示从a[0]+a[1]+.....+a[i]; 
                            //sum[j]表示从a[0]+a[1]+.....+a[i]+....+a[j];
        memset(sum,0,sizeof(sum));
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        sum[0]=a[0];
        for(int i=1;i<n;i++){
            sum[i]+=sum[i-1]+a[i];
        }
        int ans=a[0];
         for(int i=1;i<n;i++){
             for(int j=i;j<n;j++){
                 int s=sum[j]-sum[i-1];//sum[j]-sum[i-1]表示a[i]+....+a[j] 
                ans=max(ans,s); 
             }ans=max(ans,sum[n-1]);//因为s是sum[j]-sum[i-1]出来的所以至少减去了一个sum[0],
                                     //所以还得比较一次全部相加的结果 
         }cout<<ans;
        return 0;
    }

    时间复杂度:O(N)

    Kadane算法[编辑]

    Kadane算法扫描一次整个数列的所有数值,在每一个扫描点计算以该点数值为结束点的子数列的最大和(正数和)。该子数列由两部分组成:以前一个位置为结束点的最大子数列、该位置的数值。因为该算法用到了“最佳子结构”(以每个位置为终点的最大子数列都是基于其前一位置的最大子数列计算得出),该算法可看成动态规划的一个例子。

    算法可用如下Python代码实现:

    def max_subarray(A):
        max_ending_here = max_so_far = A[0]
        for x in A[1:]:
            max_ending_here = max(x, max_ending_here + x)
            max_so_far = max(max_so_far, max_ending_here)
        return max_so_far

    常用的c++代码:

    #include <bits/stdc++.h>
    
    using namespace std;
                          
    int main()
    {
        int n;
        cin>>n;
        int a[n],dp[n];//dp[i]:截至到第i项的最大和 
        for(int i=0;i<n;i++){
            cin>>a[i];
        }    dp[0]=a[0];
        int ans=a[0]; 
        for(int i=1;i<n;i++){
            dp[i]=max(dp[i-1]+a[i],a[i]);//如果a[i]>dp[i-1]+a[i],
                                        //说明现在以a[i]作为新的起点累加的结果更大 
            ans=max(ans,dp[i]);            //注意最大的不一定是dp[n-1] 
        }
        cout<<ans;
        return 0;
    }
    #include <bits/stdc++.h>
    
    using namespace std;
                          
    int main()
    {
        int n;
        cin>>n;
        int a[n]; 
        for(int i=0;i<n;i++){
            cin>>a[i];
        }    
        int ans=a[0]; 
        for(int i=1;i<n;i++){
            a[i]=max(a[i-1]+a[i],a[i]);
            ans=max(ans,a[i]); 
        }
        cout<<ans;
        return 0;
    }
    不开辟dp数组

    贪心:

    #include <bits/stdc++.h>
    
    using namespace std;
                          
    int main()
    {
        int n;
        cin>>n;
        int a[n]; 
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        int s=0,ans=a[0];    
        for(int i=0;i<n;i++){
        s+=a[i];
        ans=max(s,ans);
        if(s<0){
        s=0;    
        }
        
        }
        cout<<ans;
        return 0;
    }

      

    不一样的烟火
  • 相关阅读:
    iis7 下配置 ASP.NET MVC 项目遇到的问题 (WIN7 64位 旗舰版 第一次配置站点)
    C# .NET 使用 NPOI 读取 .xlsx 格式 Excel
    C# .NET 使用 NPOI 生成 .xlsx 格式 Excel
    SQL和T-SQL之间的区别
    .net core的服务器模式和工作站模式
    Windows Mysql8 设置大小写敏感
    每个国家对应的语言Locale和国家代码对照表(转)
    IL指令集
    使用 nvm 管理不同版本的 node 与 npm
    SSIS 包部署 Package Store 后,在 IS 中可以执行,AGENT 执行却报错
  • 原文地址:https://www.cnblogs.com/cstdio1/p/11350983.html
Copyright © 2011-2022 走看看