• <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>
            voip
            風的方向
            厚德致遠,博學敦行!
            posts - 52,comments - 21,trackbacks - 0
                     最大m子段和問題:給定由n個整數(可能為負)組成的序列a1、a2、a3...,an,以及一個正整數m,要求確定序列的m個不想交子段,使這m個子段的總和最大!
                     設b(i,j)表示數組a的前j項中i個子段和的最大值,并且第i個子段包含a[j](1<=i<=m,i<=j<=n),則所求的最優值為maxb(m,j)(m<=j<=n)。在這種定義下b(i,j)的遞推公式:b(i,j)=max{b(i,j-1)+a[j],maxb(i-1,t)+a[j](i-1<=t<j)}(1<=i<=m,i<=j<=n);b(i,j-1)+a[j]表示第i個包含a[j-1]和a[j],maxb(i-1,t)+a[j]表示第i個子段僅包含a[j]。
                     這中定義很強悍,尤其是黃色標記部分,直接把b(i,j)把a[j]限制在第i段內,然后再分a[j-1]和a[j]都在子段內和只有a[j],特殊的當m=1時,b(1,j)=max(b(1,j-1)+a[j],a[j]),1<=j<=n;如果翻譯成文字的話,就是說在數組j位置的最大和子段(包含a[j])等于數組在j-1位置的最大和子段(包含a(j-1))加上a[j]和最大和子段只有a[j]的情況的最優值,當然所求解可以表示為maxb(1,j)(1<=j<=n);其實如果光從b(1,j)=max(b(1,j-1)+a[j],a[j])這個等式本生出發我們很容易的觀察出b(1,j-1)的正負直接決定著b(1,j)的取值,然后我們可以產生這中想法,如果b(1,j-1)為正,我就繼續加,如果為負我就重新開始加!!!這樣的話,寫成程序就更簡單,其實就是前面我寫的最大子段和的動態規劃方法的解釋。。。(今天終于明白了!!!)

            代碼如下:

            #include<stdio.h>

            int MaxSum1(int m,int n,int *a)//m為切割段數,n為數組大小
            {
                
            int i,j,k,sum;
                
            if(n<m||m<1)
                    
            return 0;
                
            int **=new int *[m+1];

                
            for(i=0;i<=m;i++)
                    b[i]
            =new int[n+1];
                
            for(i=0;i<=m;i++)
                    b[i][
            0]=0;
                
            for(j=1;j<=n;j++)
                    b[
            0][j]=0;

                
            for(i=1;i<=m;i++)
                    
            for(j=i;j<=n-m+i;j++)
                    
            {
                        
            if(j>i)
                        
            {
                            b[i][j]
            =b[i][j-1]+a[j];
                            
            for(k=i-1;k<j;k++)
                            
            {
                                
            if(b[i][j]<b[i-1][k]+a[j])
                                    b[i][j]
            =b[i-1][k]+a[j];
                            }

                        }

                        
            else
                        
            {
                            b[i][j]
            =b[i-1][j-1]+a[j];
                        }

                    }

                sum
            =0;
                
            for(j=m;j<=n;j++)
                    
            if(sum<b[m][j])
                        sum
            =b[m][j];
                delete b;
                
            return sum;
            }


            //教科書上又進行了代碼優化,如下
            int MaxSum(int m,int n,int *a)
            {
                
            int i,max,j,sum;
                
            if(n<m||m<1)
                    
            return 0;

                
            int *b=new int[n+1];
                
            int *c=new int[n+1];
                b[
            0]=0;
                c[
            0]=0;
                
            for(i=1;i<=m;i++)
                
            {
                    b[i]
            =b[i-1]+a[i];
                    c[i
            -1]=b[i];
                    max
            =b[i];
                    
            for(j=i+1;j<=i+n-m;j++)
                    
            {
                        b[j]
            =b[j-1]>c[j-1]?b[j-1]+a[j]:c[j-1]+a[j];
                        c[j
            -1]=max;
                        
            if(max<b[j])
                            max
            =b[j];
                    }

                    c[i
            +n-m]=max;
                }


                sum
            =0;
                
            for(j=m;j<=n;j++)
                    
            if(sum<b[j]) 
                        sum
            =b[j];
                
            return sum;
            }



            int main()
            {
                
            int n,m;
                
            int a[100],i;
                
            while(scanf("%d %d",&m,&n)!=EOF)
                
            {
                    
            for(i=1;i<=n;i++)
                        scanf(
            "%d",&a[i]);
                    printf(
            "%d\n",MaxSum(m,n,a));
                }

                
            return 0;
            }

                  對于這段代碼我按著思想看了一遍,沒有仔細推敲過,不知道會不會是個禍患,但是測試通過了!!!
            posted on 2010-09-11 09:48 jince 閱讀(710) 評論(0)  編輯 收藏 引用 所屬分類: 算法設計與分析
            哈哈哈哈哈哈
            超级碰碰碰碰97久久久久| 嫩草伊人久久精品少妇AV| 久久丫精品国产亚洲av不卡| 无码精品久久一区二区三区| AA级片免费看视频久久| 97久久国产亚洲精品超碰热| 亚洲欧美日韩中文久久| 思思久久精品在热线热| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区| av午夜福利一片免费看久久| 久久婷婷五月综合97色| 亚洲av日韩精品久久久久久a| 亚洲狠狠婷婷综合久久久久| 新狼窝色AV性久久久久久| 久久国产高潮流白浆免费观看| 国产成人久久精品一区二区三区 | 精品国产99久久久久久麻豆| 思思久久精品在热线热| 无码人妻久久一区二区三区| 久久精品国产亚洲av影院| 国产精品久久久久jk制服| 99久久无码一区人妻| 欧美久久一区二区三区| 久久五月精品中文字幕| 久久久一本精品99久久精品88| 亚洲人成网亚洲欧洲无码久久 | 亚洲国产精品久久电影欧美| 久久婷婷五月综合色高清| 伊人久久综在合线亚洲2019| 人人狠狠综合88综合久久| 亚洲精品国产字幕久久不卡| 久久久久免费精品国产| 色婷婷久久久SWAG精品| 久久ZYZ资源站无码中文动漫| 国产午夜福利精品久久| 国产免费久久精品99re丫y| 国产麻豆精品久久一二三| 久久中文精品无码中文字幕| 日产精品久久久久久久| 精品久久人人爽天天玩人人妻 | 久久久久成人精品无码中文字幕|