POJ1050 HDOJ1081 TO THE MAX

求矩阵的最大子矩阵

DP典型例题:

Pku 1050 To The Max  http://acm.pku.edu.cn/JudgeOnline/problem?id=1050

Hdu 1081 To The Max http://acm.hdu.edu.cn/showproblem.php?pid=1081

 

题目的意思很简单,在一个矩阵里面找它的子矩阵,使得子矩阵数值之和到达最大。其实就是最大子段和问题在二维空间上的推广。考察下面题目中的例子:

0         -2  -7  0

9           2  -6  2

-4  1  -4   7

-1  8  0   -2

我们分别用i j表示起始行和终止行,遍历所有的可能:

for(i=1;i<=n;i++)

    for(j=i;j<=n;j++) {}

我们考察其中一种情况 i=2 j=4,这样就相当与选中了2 3 4三行,求那几列的组合能获得最大值,由于总是 2 3 4行,所以我们可以将这3行”捆绑”起来,变为求 4(9-4-1),11(8+2+1),-10(-6-4+0),7(7+2-2)的最大子段和,ok,问题成功转化为一维的情况!

  1. #include <iostream>  
  2. using namespace std;  
  3. int a[102][102],b[102];  
  4. int f[10002];  
  5. int main()  
  6. {  
  7.     int i,j,n,k,m,t,l,q;  
  8.     int maxnum, max1;  
  9.   
  10.     while (scanf("%d",&n)!=EOF)  
  11.     {  
  12.         for (i=0;i<n;i++)  
  13.         {  
  14.             for (j=0;j<n;j++)  
  15.             {  
  16.                 scanf("%d",&a[i][j]);  
  17.             }  
  18.         }  
  19.         max1 = 0;  
  20.         for (i=0;i<n;i++)  
  21.         {  
  22.             for (j=0;j<n;j++)  
  23.             {  
  24.                 if (i == j) //只有一行的情况,我们只单纯地抽取这行  
  25.                 {  
  26.                     for (k=0;k<n;k++)  
  27.                     {  
  28.                         b[k] = a[i][k];   
  29.                     }  
  30.                 }  
  31.                 else //如果有多行,那么捆绑每一列的和,使之成为一行  
  32.                 {  
  33.                     for (k=0;k<n;k++)  
  34.                     {  
  35.                         b[k] = 0;  
  36.                         for (l=i;l<=j;l++)  
  37.                         {  
  38.                             b[k] += a[l][k];  
  39.                         }  
  40.                     }  
  41.                 }  
  42.                 int sum=0;  
  43.                 maxnum=-1001;  
  44.                 int first =0;  
  45.                 int last = 0;  
  46.                 int temp = 0;  
  47.                 for (k=0;k<n;k++)  
  48.                 {  
  49.                     sum += b[k];  
  50.                     if (sum > maxnum)  
  51.                     {  
  52.                         maxnum = sum;  
  53.                         first = temp;  
  54.                         last = k;  
  55.                     }  
  56.                     if (sum < 0)  
  57.                     {  
  58.                         sum = 0;  
  59.                         temp = k+1;  
  60.                     }  
  61.                 }//for  
  62.                 if (maxnum > max1)  
  63.                 {  
  64.                     max1 = maxnum;  
  65.                 }  
  66.             }  
  67.         }  
  68.         printf("%d\n",max1);  
  69.     }  
  70.     return 0;  
  71. }
posted on 2011-05-18 08:50  fly_away  阅读(207)  评论(0编辑  收藏  举报