【二维DP】最大子阵

来源:互联网 发布:linux查看磁盘使用情况 编辑:程序博客网 时间:2024/05/21 03:28
给定一个 n×m 的矩阵 A,求 A 中的一个非空子矩阵,使这个子矩阵中的元素和最大。其中,A 的子矩阵指在 A 中行和列均连续的一部分。

输入格式

输入的第一行包含两个整数n,m(1≤n,m≤50),分别表示矩阵 A 的行数和列数。

接下来 n 行,每行 m 个整数,表示矩阵 (不超过int)

输出格式

输出一行,包含一个整数,表示 A 中最大子矩阵的元素和。

样例输入

3 3
2 -4 1
-1 2 1
4 -2 2
样例输出

6


参考
http://zzssy.win/forum.php?mod=viewthread&tid=50&extra=page%3D1
增加了一维
那么我们就在一维状态上枚举另一维,复杂度O(n^3)
也就是先转化为一维的,将i---j行压缩成一维的,找ans
代码如下:
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. int n,m,a[55][55],zip[55],f[55][55],ans=-1000000000;

  7. void scan(){
  8.         scanf("%d%d",&n,&m);
  9.         for(int i=1;i<=n;i++)
  10.         for(int ii=1;ii<=m;ii++)
  11.         scanf("%d",&a[i][ii]);
  12. }
  13. void dp(){
  14.         for(int kaishi=1;kaishi<=n;kaishi++){
  15.                 memset(zip,0,sizeof(zip));
  16.                 for(int jieshu=kaishi;jieshu<=n;jieshu++){
  17.                         for(int t=1;t<=m;t++){
  18.                                 zip[t]+=a[jieshu][t];
  19.                         }
  20.                         int sum=0;
  21.                         for(int i=1;i<=m;i++){
  22.                                 if(sum<=0) sum=zip[i];
  23.                                 else sum=sum+zip[i];
  24.                                 ans=max(ans,sum);
  25.                         }
  26.                 }
  27.         }
  28.         
  29. }
  30. void debug(){
  31.         for(int i=1;i<=n;i++){
  32.         for(int ii=1;ii<=m;ii++)
  33.         printf("%d ",f[i][ii]);
  34.         printf("\n");
  35.         } 
  36.         
  37. }

  38. int main(){
  39.         scan();
  40.         dp();
  41.         //debug(); 
  42.         printf("%d",ans);
  43. }
原创粉丝点击