• <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)  編輯 收藏 引用 所屬分類: 算法設計與分析
            哈哈哈哈哈哈
            亚洲国产精品无码久久SM| 欧美丰满熟妇BBB久久久| 久久久久国产一级毛片高清版| 精品久久久久久无码专区| 国产Av激情久久无码天堂| 久久国产精品99精品国产987| 精品久久久久久中文字幕| 久久久久久久久久久免费精品| 国内精品久久久久影院亚洲| 久久99久久99精品免视看动漫| 久久婷婷五月综合色99啪ak| 亚洲中文字幕久久精品无码喷水| 色综合久久综合网观看| 久久精品国产亚洲AV影院| 国产成人精品久久一区二区三区av| 麻豆久久| 三级片免费观看久久| 久久免费国产精品一区二区| 亚洲av成人无码久久精品| 亚洲欧美国产精品专区久久| 91久久精品电影| MM131亚洲国产美女久久| 久久精品青青草原伊人| 久久人妻少妇嫩草AV蜜桃| 久久精品人人做人人爽电影| 三上悠亚久久精品| 久久午夜夜伦鲁鲁片免费无码影视| 99久久国产热无码精品免费久久久久| 亚洲综合伊人久久综合| 中文国产成人精品久久亚洲精品AⅤ无码精品| 99久久超碰中文字幕伊人 | 精品永久久福利一区二区| 亚洲欧美久久久久9999| 国产伊人久久| 久久久久亚洲爆乳少妇无| 7国产欧美日韩综合天堂中文久久久久 | 人妻少妇久久中文字幕一区二区| 中文字幕精品久久久久人妻| 久久无码人妻精品一区二区三区| 91久久成人免费| 久久高清一级毛片|