• <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

            求最大連續(xù)子向量最大和

                                             最大連續(xù)子向量和

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


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

            #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 ;    
              }

                  


              解法二 
                 第一種解法比較常見,但是此種解法則不常用。定義個(gè)數(shù)據(jù)S ,則S[i] 表示數(shù)組a[0]到a[i]之間的元素之和,那么S[j]-S[i] 的差值,表示
                 a[i]到a[j]之間和。  本題的問(wèn)題,就是求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)級(jí)別的,實(shí)質(zhì)上可以使用分治法來(lái)解決此問(wèn)題。

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


              

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


            #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]) ;
                 
            //計(jì)算左部分的最大值
                 
                 
            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) )) ;
                   
                 
             }



             第三個(gè)算法的時(shí)間復(fù)雜度為o(n *  log(n)) ,通過(guò)這個(gè)題目來(lái)學(xué)習(xí)分治法。




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

                

            /*
             通過(guò)線性算法解決問(wèn)題 
            */


            #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) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久久久成人精品无码 | 欧洲成人午夜精品无码区久久| 久久亚洲天堂| 国产偷久久久精品专区| 久久er99热精品一区二区| 国内精品久久久久久久coent| 久久一区二区三区99| 亚洲AV乱码久久精品蜜桃| 中文字幕久久欲求不满| 久久综合亚洲色HEZYO社区| 色综合久久久久久久久五月| 中文精品久久久久国产网址| 久久久久久国产精品无码下载 | 久久久久se色偷偷亚洲精品av| 成人妇女免费播放久久久| 久久久久这里只有精品 | 亚洲国产精品无码久久久秋霞2 | 久久国产精品-久久精品| 久久久黄色大片| 国产精品九九久久精品女同亚洲欧美日韩综合区| 久久久精品人妻无码专区不卡 | 久久精品无码一区二区无码| 久久久久国产亚洲AV麻豆| 国产精品久久国产精麻豆99网站 | 久久精品国产AV一区二区三区| 国产精品99久久精品爆乳| MM131亚洲国产美女久久| 久久午夜伦鲁片免费无码| 亚洲七七久久精品中文国产| 一本久久久久久久| 国产精品狼人久久久久影院| 色综合久久中文综合网| 久久精品国产亚洲一区二区| 91久久精一区二区三区大全| 久久久久亚洲AV无码麻豆| 久久精品人人做人人爽97| 久久99精品久久久大学生| 国产成人无码精品久久久性色 | 99久久精品免费观看国产| 9999国产精品欧美久久久久久| 热99re久久国超精品首页|