• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            jake1036

            求最大連續子向量最大和

                                             最大連續子向量和

               一個整形數組,求其間連續的子向量,使其子向量的和最大。 如一組數組元素為 31 , -41 ,59 , 26 ,-53 ,58 , 97 , -93 , -23 , 84
                  【2 , 6】之間的子向量之和最大。定義若數組中的元素全部為負數,則最大和值為0 。 若數組中的數字全部為正數,則最大和值即為數組中的全部元素之和。


                    解法一:
                    經過建模轉換,即是求在[1,n]中 求[i,j]之和的最大值,使用暴力解法,算出任意[i,j]之間的各個值,然后取最大值,即為所求。
                     

            #include <iostream>
            using namespace std ;
             
              
            int sumMax(int *a , int n)
              
            {
                    
                    
            int max = 0 ,sum = 0 ; //
                    for(int i = 0 ; i < n ; i++)
                    
            {
                      sum 
            = 0 ;      
                      
            for(int j = i ; j < n ; j++)
                       
            {
                           sum 
            += a[j] ;
                           
            if(max < sum)
                            
            {
                              max 
            = sum ;      
                            }
                 
                       }

                    }

                  
                  
            return max ;
              }

             
             
              
            int main()
              
            {
                
            int a[] = {31 , -41 ,59 , 26 ,-53 ,58 , 97 , -93-23 , 84} ;
                cout
            <<"max"<<sumMax(a , 8) ;
                cin.
            get() ;
               
                
            return 0 ;    
              }

                  


              解法二 
                 第一種解法比較常見,但是此種解法則不常用。定義個數據S ,則S[i] 表示數組a[0]到a[i]之間的元素之和,那么S[j]-S[i] 的差值,表示
                 a[i]到a[j]之間和。  本題的問題,就是求S[j]-S[i]的最大值。
               

            #include <iostream>
             
            using namespace std ;
             
             
            int sumMax(int * s , int n )
             
            {
                 
            int sum = 0 , max = 0 ;
                 
            for(int i = 0 ; i < n ; i++)
                  
            {        
                    
            for(int j = i + 1;j < n  ;j++
                     
            {
                        sum 
            = s[j] - s[i] ;
                        
            if(sum > max)
                          max 
            = sum ;        
                     }

                  }

                  
            return max ;
                 
             }

             
             
            int main()
             
            {
                 
               
            int a[] = {31 , -41 ,59 , 26 ,-53 ,58 , 97 , -93-23 , 84} ;
               
            int * s = new int[8];
               
            int sum = 0 ;
               
            for(int i = 0 ; i < 8 ; i++)
                
            {
                   sum 
            += a[i] ;    
                   s[i] 
            = sum ;
                }
             
                 
                 
                 cout
            <<"max"<<sumMax(s , 8);
                 
                 
               delete [] s ;
               cin.
            get() ; 
               
            return 0 ;    
             }
             


               綜上,以上的兩種解法都是O(n*n)級別的,實質上可以使用分治法來解決此問題。

              解法三:
               利用分治法解決最大子序列和問題
              可以將原數組從中間元素開始分成兩個部分,左邊部分最大子序列和為Ml,右邊部分最大子序列和為Mr,還有一種情況即整個數組的
               最大子序列和存在左右兩個部分之間,記為Mc。 所求結果即為Ml 、Mr、Mc 三者的最大值。利用遞歸算法解決此問題。


              

            /*
             該算法使用了分治法,求最大子序列的和問題 
            */


            #include 
            <iostream>
             
            using namespace std ;
             
             inline 
            int Max(int , int) ;
             
            int sumMax(int * a , int l , int r);

             
             
             
            int main()
             
            {
              
            int a[] = {31 , -41 ,59 , 26 ,-53 ,58 , 97 , -93-23 , 84} ;
              cout
            <<sumMax(a , 0 , 9) ; 
              cin.
            get() ;
               
            return 0 ;    
             }

             
             
             
             inline 
            int Max(int x , int y)
             
            {
                
            return x>? x : y ;       
                    
             }
             
             
             
              
            int sumMax(int * a , int l , int r)
             
            {
                 
            if(l > r)
                   
            return 0 ;
                 
            if(l == r)  
                  
            return Max(0 , a[l]) ;
                 
            //計算左部分的最大值
                 
                 
            int m = (l + r) >> 1 ;
                 
                 
            int lmax = 0 , sum = 0 ;
                 
            for(int i = m ; i >= 0 ; i--//左部分從中間向左依次疊加,然后判斷是否獲得最大值 
                  
                   sum 
            += a[i] ;
                   lmax 
            = Max(sum , lmax) ;  //左邊最大值    
                   }

                   
                  
            int rmax = 0 ;
                   sum 
            = 0 ;
                  
            for(int j =  m + 1; j <= r ; j++)//右部分從中間向右依次疊加,然后判斷是否獲得最大值
                    {
                     sum 
            += a[j] ;
                     rmax 
            = Max(sum , rmax) ;  //右邊最大值
                    }
                
                  
            return Max(lmax + rmax , Max(sumMax(a , l , m) , sumMax(a , m + 1 , r) )) ;
                   
                 
             }



             第三個算法的時間復雜度為o(n *  log(n)) ,通過這個題目來學習分治法。




              第四種解法:
                   該解法為一線性解法,算法復雜度為O(n) ,定義maxEndingHere為截止到a[j]處的最大子數組之和,則a[j+1]處的最大子數組之和為
                  max(maxEndingHere + a[j + 1] , 0) ,而我們的所求maxSofar即為各個位置最大的maxEndingHere。

                

            /*
             通過線性算法解決問題 
            */


            #include 
            <iostream>
             
            using namespace std ;
             inline 
            int Max(int , int) ;
             
            int sumMax(int a[] , int n) ; 
             
             
            int main()
             
            {
               
            int a[] = {31 , -41 ,59 , 26 ,-53 ,58 , 97 , -93-23 , 84} ;
              cout
            <<sumMax(a  , 9) ; 
              cin.
            get() ;
               
            return 0 ;    
             }
             

             inline 
            int Max(int x , int y)
             
            {
                
            return x>? x : y ;       
                    
             }
             
             
              
            int sumMax(int a[] , int n) 
                  
            {
                    
            int maxEndingHere = 0 , maxSoFar = 0 ; //maxEndingHere 表示截止到位置i處的最大子序列和 
                    for(int i = 0 ; i < n ; i++
                     
            {
                       maxEndingHere 
            = Max(maxEndingHere + a[i] , 0 ) ; 
                       maxSoFar 
            = Max(maxEndingHere , maxSoFar) ;      
                     }

                     
                     
            return maxSoFar ;          
                  }


                






                      
               

            posted on 2011-03-12 15:43 kahn 閱讀(1007) 評論(0)  編輯 收藏 引用

            2020久久精品亚洲热综合一本| 精品熟女少妇a∨免费久久| 久久免费视频观看| 久久国产成人| 久久婷婷人人澡人人爽人人爱 | 伊人久久综在合线亚洲2019| 久久久久久久综合日本亚洲| 色婷婷综合久久久久中文字幕| 久久精品国产亚洲av麻豆图片| 2021久久国自产拍精品| 久久精品国产99国产精品| 99蜜桃臀久久久欧美精品网站 | 久久综合中文字幕| 亚洲国产一成久久精品国产成人综合| 一本色道久久综合亚洲精品| 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 人人妻久久人人澡人人爽人人精品| 久久精品中文无码资源站| 久久精品九九亚洲精品天堂| 久久99九九国产免费看小说| 久久精品国产91久久麻豆自制 | 777午夜精品久久av蜜臀| 国产精品无码久久四虎| 色欲久久久天天天综合网精品| 久久影视综合亚洲| 精品久久久久中文字| 久久久久AV综合网成人 | 久久香蕉国产线看观看猫咪?v| 亚洲国产精品无码久久久秋霞2 | 午夜精品久久久久久99热| 欧美久久一区二区三区| 99久久国产免费福利| 久久综合狠狠色综合伊人| 久久久噜噜噜久久中文福利| 亚洲人AV永久一区二区三区久久| 精品久久久久久久久中文字幕| 漂亮人妻被黑人久久精品| 亚洲AV无一区二区三区久久| 久久AV无码精品人妻糸列| 97久久国产露脸精品国产| 久久婷婷五月综合色奶水99啪|