• <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 閱讀(695) 評論(0)  編輯 收藏 引用 所屬分類: 算法設計與分析
            哈哈哈哈哈哈
            18禁黄久久久AAA片| 久久综合九色欧美综合狠狠 | 久久99精品国产99久久| 日本久久久精品中文字幕| 青青草国产成人久久91网| 久久久久国产精品三级网| 中文字幕精品无码久久久久久3D日动漫 | 久久综合噜噜激激的五月天| 久久久久久国产精品免费无码| 天天综合久久久网| 久久久久久伊人高潮影院| 99久久er这里只有精品18| 国产成人精品综合久久久| 久久久久久伊人高潮影院| 91麻豆精品国产91久久久久久| 无码人妻久久一区二区三区蜜桃| 久久人妻少妇嫩草AV无码专区| 精品久久久久久无码中文野结衣| 精品久久久一二三区| 99久久精品午夜一区二区| 久久久黄色大片| 久久99精品久久久久久齐齐| 久久久久亚洲AV无码观看| 精品久久国产一区二区三区香蕉| 一本色道久久99一综合| 精品久久久久久久久久久久久久久| 久久精品国产男包| 久久男人中文字幕资源站| 97久久精品无码一区二区天美| 亚洲精品97久久中文字幕无码| 丰满少妇高潮惨叫久久久| 日本五月天婷久久网站| 久久av免费天堂小草播放| AV无码久久久久不卡蜜桃| 伊人久久综合无码成人网| 欧美久久久久久精选9999| 国产精品久久久久久一区二区三区| 97香蕉久久夜色精品国产| 久久国产精品视频| 国产精品一久久香蕉产线看| 久久国语露脸国产精品电影|