可以识别我的算法中的错误吗?

时间:2016-03-10 20:11:03

标签: c++ algorithm matrix dynamic-programming

问题陈述就像这样

给定二进制矩阵,找出所有1的最大尺寸方形子矩阵。

例如,请考虑以下二进制矩阵。

   0  1  1  0  1 
   1  1  0  1  0 
   0  1  1  1  0
   1  1  1  1  0
   1  1  1  1  1
   0  0  0  0  0

具有所有设置位的最大平方子矩阵是3

我创建了一个基于memoization的dp解决方案

我的节目是

#include<bits/stdc++.h>
using namespace std;

#define R 6
#define C 5

int getmaxsizesummatrix(int mat[R][C],vector< vector<int> > &v,int r,int c)
{
    if(r<0||c<0)
        return 0;

    if(r==0||c==0)
    {
        v[r][c]=mat[r][c];
         return mat[r][c];
    }


    if(v[r][c]==-1)
    {
    int m=INT_MIN;
    int flag=1;
        for(int j=0;j<=r;j++)
        {
            for(int k=0;k<=c;k++)
            {

                int x,y,z;
                x = getmaxsizesummatrix(mat,v,j-1,k-1);
                y = getmaxsizesummatrix(mat,v,j-1,k);
                z = getmaxsizesummatrix(mat,v,j,k-1);



                if(mat[j][k]==1)
                {
                m=max(m,min(x,min(y,z))+1);
                }
                else
                {    
                 m=max(m,min(x,min(y,z)));   
                }
            }
        }
    return v[r][c] = m;
    }
    else
    {
        return v[r][c];
    }
}

int main()
{
    int M[R][C] = {{0, 1, 1, 0, 1},
                   {1, 1, 0, 1, 0},
                   {0, 1, 1, 1, 0},
                   {1, 1, 1, 1, 0},
                   {1, 1, 1, 1, 1},
                   {0, 0, 0, 0, 0}};
    vector< vector<int> > v(R+1,vector<int>(C+1,-1));
  cout<<getmaxsizesummatrix(M,v,6,5);
  return 0;
}

我得到4作为输出。

任何人都可以纠正我的做法吗?

2 个答案:

答案 0 :(得分:0)

不确定这一点,但从它的外观来看 - 你是一个人。

注意:

#define R 6
#define C 5
...
int M[R][C] = {...};
getmaxsizesummatrix(M,v,6,5); 
...
int getmaxsizesummatrix(int mat[R][C],vector< vector<int> > &v,int r,int c) // r=6, c=5
{
    ...
    for(int j=0;j<=r;j++)
    {
        for(int k=0;k<=c;k++)
        {
             ...
        }
    }
}

或许解决方案是严格检查j<r而不是j<=r

答案 1 :(得分:0)

我已经修改了一些代码以使其正常工作

以下是解释:实施DP解决方案时遇到2个问题

  1. dp vector v[][]
  2. 的定义
  3. 你自下而上混淆了自上而下的实施,使调试更加困难
  4. 对于< vs <=作为提及的其他答案,这不是您实施中的问题,因为它是异常实现,如上面第2点所述,但你必须通过R-1&amp; C-1代替函数,因此您仍然可以在不超出约束的情况下计算v[r][c]

    我将重点关注以上两点。

    对于1,你能告诉我你对v[][]的定义是什么吗? 它是到目前为止找到的最大方形长度方形的右下角是(i,j)的最大方形长度?这是一个巨大的选择差异,当您使用v[][]递归计算另一个v[][]时,您应该采用第二个选项,这是我为您修改的代码的一部分。例如,您的代码会在1(从0开始)时提供v[1][2] & v[1][4],而我的0mat[1][2] & mat[1][4]0并且不能形成任何方格。修改后,现在您的代码将计算采用第二个定义的v[][],因此我们必须遍历整个v[][]以获得答案,而不是简单地打印v[R][C]

    对于2,你的实现有点混乱,因为你混淆了自下而上&amp;自上而下的实施。换句话说,你混淆了 for-loop迭代&amp; 递归,对于包括此问题在内的大多数DP问题,您只需选择一种方法,但不能同时选择两种方法。您正在尝试递归方法,它会调用Function(R,C)来获得答案,但在每次调用中,您每次都会循环遍历数组,这是冗余且容易出错的。你应该

    1. 自下而上:根本不使用函数,不进行递归,只需设置基本情况(第1行),并使用代码中显示的两个for循环从小索引到大索引构建v[][]
    2. 自上而下:在递归函数中使用递归,no for循环!!只需编写类似Func(R,C) = max(Func(R-1,C-1), Func(R-1,C), Func(R,C-1))+1的基本案例来保护负面索引,已计算v[r][c]等。
    3. 请查看代码并告诉我是否遗漏或不清楚,如果需要,我会解释更多。

      #include<bits/stdc++.h>
      using namespace std;
      
      #define R 6
      #define C 5
      
      int getmaxsizesummatrix(int mat[R][C],vector< vector<int> > &v,int r,int c)
      {
          if(r<0||c<0)
              return 0;
      
          if(r==0||c==0)
          {
              v[r][c]=mat[r][c];
               return mat[r][c];
          }
      
      
          if(v[r][c]==-1)
          {
      		int m=INT_MIN;
              for(int j=0;j<=r;j++)
              {
                  for(int k=0;k<=c;k++)
                  {
                      int x,y,z;
                  	x = getmaxsizesummatrix(mat,v,j-1,k-1);
                  	y = getmaxsizesummatrix(mat,v,j-1,k);
                  	z = getmaxsizesummatrix(mat,v,j,k-1);
                   
      			
                      if(mat[j][k]==1)
                      {
                      	m=max(m,min(x,min(y,z))+1);
                      }
                      else
                      {    
                       	m=max(m,min(x,min(y,z)));   
                      }
                  }
              }
              if(mat[r][c] == 0) return v[r][c] = 0; // <-- Add this line
              return v[r][c] = m;
          	
          }
          else
          {
              return v[r][c];
          }
      }
      
      int main()
      {
          int M[R][C] = {{0, 1, 1, 0, 1},
                         {1, 1, 0, 1, 0},
                         {0, 1, 1, 1, 0},
                         {1, 1, 1, 1, 0},
                         {1, 1, 1, 1, 1},
                         {0, 0, 0, 0, 0}};
         vector< vector<int> > v(R+1,vector<int>(C+1,-1));
        
        getmaxsizesummatrix(M,v,R-1,C-1);  // <-- Change Parameter
        
      
        // Change the answer-optain code 
        int ans = INT_MIN;
        for(int i=0; i<R; i++) 
        	for(int j=0; j<C;j++) ans = max(ans, v[i][j]);
        
        cout << ans << endl;
        return 0;
      }