• <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 閱讀(1004) 評論(0)  編輯 收藏 引用

            国产精品久久99| 久久精品国产久精国产| 日韩亚洲国产综合久久久| 狠狠色综合久久久久尤物 | 国产精品美女久久久免费| 国产午夜电影久久| 久久综合亚洲鲁鲁五月天| 久久精品国产亚洲AV麻豆网站| 久久伊人精品青青草原高清| 污污内射久久一区二区欧美日韩 | 久久中文骚妇内射| 综合人妻久久一区二区精品| 18岁日韩内射颜射午夜久久成人| 91久久精品国产91性色也| 大香伊人久久精品一区二区 | 欧美午夜A∨大片久久 | 香蕉久久久久久狠狠色| 久久久精品人妻一区二区三区蜜桃| 99久久精品免费国产大片| 亚洲综合精品香蕉久久网| 久久久久人妻一区精品果冻| 日产精品久久久久久久| 国产精品gz久久久| 精品熟女少妇a∨免费久久| 亚洲欧洲久久av| 97超级碰碰碰碰久久久久| 久久精品国产亚洲AV麻豆网站| 久久夜色精品国产亚洲| 亚洲&#228;v永久无码精品天堂久久 | 亚洲精品乱码久久久久久久久久久久| 久久久青草青青亚洲国产免观| 亚洲精品国产美女久久久| 日本亚洲色大成网站WWW久久 | 久久综合九色欧美综合狠狠| 97精品久久天干天天天按摩| 久久青青草原精品国产| 亚洲国产精品无码久久久秋霞2| 欧美黑人激情性久久| 久久人人爽人人爽人人片AV东京热| 久久精品国产一区二区| 狠狠久久综合伊人不卡|