乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      PKU 1050 動(dòng)態(tài)規(guī)劃-解決最大子矩陣問(wèn)題

       ShangShujie 2009-10-11

       最大子矩陣問(wèn)題:
      問(wèn)題描述:(具體見(jiàn)http://acm.pku.edu.cn/JudgeOnline/showproblem?problem_id=1050)
         給定一個(gè)n*n(0<n<=100)的矩陣,請(qǐng)找到此矩陣的一個(gè)子矩陣,并且此子矩陣的各個(gè)元素的和最大,輸出這個(gè)最大的值。
      Example:
      0 -2 -7 0
      9 2 -6 2
      -4 1 -4 1
      -1 8 0 -2
      其中左上角的子矩陣:
      9 2
      -4 1
      -1 8
      此子矩陣的值為9+2+(-4)+1+(-1)+8=15。
      我們首先想到的方法就是窮舉一個(gè)矩陣的所有子矩陣,然而一個(gè)n*n的矩陣的子矩陣的個(gè)數(shù)當(dāng)n比較大時(shí)時(shí)一個(gè)很大的數(shù)字 O(n^2*n^2),顯然此方法不可行。
      怎么使得問(wèn)題的復(fù)雜度降低呢?對(duì)了,相信大家應(yīng)該知道了,用動(dòng)態(tài)規(guī)劃。對(duì)于此題,怎么使用動(dòng)態(tài)規(guī)劃呢?

      讓我們先來(lái)看另外的一個(gè)問(wèn)題(最大子段和問(wèn)題):
          給定一個(gè)長(zhǎng)度為n的一維數(shù)組a,請(qǐng)找出此數(shù)組的一個(gè)子數(shù)組,使得此子數(shù)組的和sum=a[i]+a[i+1]+……+a[j]最大,其中i>=0,i<n,j>=i,j<n,例如
         31 -41 59 26 -53 58 97 -93 -23 84
      子矩陣59+26-53+58+97=187為所求的最大子數(shù)組。
      第一種方法-直接窮舉法:
         maxsofar=0;
         for i = 0 to n
         {
             for j = i to n
             {
                  sum=0;
                  for k=i to j
                      sum+=a[k]
                  if (maxsofar>sum)
                     maxsofar=sum;
             }
         }

      第二種方法-帶記憶的遞推法:
         cumarr[0]=a[0]
         for i=1 to n      //首先生成一些部分和
         {
              cumarr[i]=cumarr[i-1]+a[i];      
         }

         maxsofar=0
         for i=0 to n
         {
             for j=i to n     //下面通過(guò)已有的和遞推
             {
                 sum=cumarr[j]-cumarr[i-1]
                 if(sum>maxsofar)
                     maxsofar=sum
             }
         }
      顯然第二種方法比第一種方法有所改進(jìn),時(shí)間復(fù)雜度為O(n*n)。

      下面我們來(lái)分析一下最大子段和的子結(jié)構(gòu),令b[j]表示從a[0]~a[j]的最大子段和,b[j]的 當(dāng)前值只有兩種情況,(1) 最大子段一直連續(xù)到a[j] (2) 以a[j]為起點(diǎn)的子段,不知有沒(méi)有讀者注意到還有一種情況,那就是最大字段沒(méi)有包含a[j],如果沒(méi)有包含a[j]的話,那么在算b[j]之前的時(shí)候我 們已經(jīng)算出來(lái)了,注意我們只是算到位置為j的地方,所以最大子斷在a[j]后面的情況我們可以暫時(shí)不考慮。
      由此我們得出b[j]的狀態(tài)轉(zhuǎn)移方程為:b[j]=max{b[j-1]+a[j],a[j]},
      所求的最大子斷和為max{b[j],0<=j<n}。進(jìn)一步我們可以將b[]數(shù)組用一個(gè)變量代替。
      得出的算法如下:
          int maxSubArray(int n,int a[])
          {
              int b=0,sum=-10000000;
              for(int i=0;i<n;i++)
              {
                   if(b>0) b+=a[i];
                   else b=a[i];
                   if(b>sum) sum=b; 
              }
              return sum;
          }
      這就是第三種方法-動(dòng)態(tài)規(guī)劃。


      現(xiàn)在回到我們的最初的最大子矩陣的問(wèn)題,這個(gè)問(wèn)題與上面所提到的最大子斷有什么聯(lián)系呢?
      假設(shè)最大子矩陣的結(jié)果為從第r行到k行、從第i列到j(luò)列的子矩陣,如下所示(ari表示a[r][i],假設(shè)數(shù)組下標(biāo)從1開(kāi)始):
      | a11 …… a1i ……a1j ……a1n |
      | a21 …… a2i ……a2j ……a2n |
      | .     .     .    .   .    .    .   |
      | .     .     .    .   .    .    .   |
      | ar1 …… ari ……arj ……arn |
      | .     .     .    .   .    .    .   |
      | .     .     .    .   .    .    .   |
      | ak1 …… aki ……akj ……akn |
      | .     .     .    .   .    .    .   |
      | an1 …… ani ……anj ……ann |

      那么我們將從第r行到第k行的每一行中相同列的加起來(lái),可以得到一個(gè)一維數(shù)組如下:
      (ar1+……+ak1, ar2+……+ak2, ……,arn+……+akn)
      由此我們可以看出最后所求的就是此一維數(shù)組的最大子斷和問(wèn)題,到此我們已經(jīng)將問(wèn)題轉(zhuǎn)化為上面的已經(jīng)解決了的問(wèn)題了。

      此題的詳細(xì)解答如下(Java描述):

      import java.util.Scanner;
      public class PKU_1050
      {
           private int maxSubArray(int n,int a[])
            {
                  int b=0,sum=-10000000;
                  for(int i=0;i<n;i++)
                   {
                        if(b>0) b+=a[i];
                        else b=a[i];
                         if(b>sum) sum=b;
                  }
                  return sum; 
            }
            private int maxSubMatrix(int n,int[][] array)
             {
                  int i,j,k,max=0,sum=-100000000;
                  int b[]=new int[101];
                  for(i=0;i<n;i++)
                  {
                         for(k=0;k<n;k++)//初始化b[]
                        {
                              b[k]=0;
                        }
                        for(j=i;j<n;j++)//把第i行到第j行相加,對(duì)每一次相加求出最大值
                        {
                              for(k=0;k<n;k++)
                              {
                                     b[k]+=array[j][k];
                              }
                              max=maxSubArray(k,b); 
                              if(max>sum)
                              {
                                       sum=max;
                              }
                        }
                  }
                  return sum;
            }
            public static void main(String args[])
             {
                  PKU_1050 p=new PKU_1050();
                  Scanner cin=new Scanner(System.in);
                   int n=0;
                  int[][] array=new int[101][101];
                   while(cin.hasNext())
                   {
                              n=cin.nextInt();  
                              for(int i=0;i<n;i++)
                              {
                                         for(int j=0;j<n;j++)
                                         {
                                                    array[i][j]=cin.nextInt();
                                         }
                              }
                              System.out.println(p.maxSubMatrix(n,array));
                   }
             }
      }

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多