• <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)  編輯 收藏 引用 所屬分類: 算法設計與分析
            哈哈哈哈哈哈
            色综合久久夜色精品国产| 久久天天躁狠狠躁夜夜avapp| 久久久久久亚洲Av无码精品专口| 色偷偷91久久综合噜噜噜噜| 精品久久久久久无码国产| 国产91久久综合| 国产精品成人99久久久久91gav | 国产V亚洲V天堂无码久久久| 亚洲中文字幕无码一久久区| 国产成人久久精品一区二区三区 | 国产精品久久久久9999| 久久精品水蜜桃av综合天堂 | 国产成人精品久久| 国产精品美女久久久久av爽 | 蜜臀av性久久久久蜜臀aⅴ麻豆| 97精品依人久久久大香线蕉97| 亚洲国产精品无码久久久秋霞2| 色婷婷综合久久久中文字幕| 国产精品美女久久久m| 97精品国产97久久久久久免费| 狠狠综合久久综合中文88| 最新久久免费视频| 色诱久久久久综合网ywww| 久久精品草草草| 亚洲色欲久久久久综合网| 麻豆一区二区99久久久久| 丁香久久婷婷国产午夜视频| 免费精品国产日韩热久久| 国产V亚洲V天堂无码久久久| 久久伊人亚洲AV无码网站| 久久精品中文闷骚内射| 狠狠色伊人久久精品综合网| 国产激情久久久久久熟女老人| 色综合合久久天天综合绕视看| 国产69精品久久久久观看软件 | 性高湖久久久久久久久| 一级做a爰片久久毛片16| 久久亚洲精品无码aⅴ大香| 久久久精品一区二区三区| 九九精品久久久久久噜噜| 国产午夜精品久久久久九九|