UVa 836 - Largest Submatrix

题目:给你一个n*n的01矩阵,求里面最大的1组成的矩形的米娜及。

分析:dp,单调队列。UVa 1330同题,只是输入格式变了。

            我们将问题分解成最大矩形,即求解以k行为底边的图形中的最大矩形,然后合并,求最大的矩形;
          
            预处理: 求出以每行为底边的每一列从底边开始向上的最大连续1的高度MaxH。 O(N^2) ;

            dp:对于每一层底边,我们利用单调队列求解出本行的最大矩形。 O(N);

            关于单调队列的求解分析,可参照zoj1985的题解;

            总体时间:T(N) = O(N^2)+O(N)*O(N) = O(N^2)。

说明:注意数据读入格式。

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>

using namespace std;

char maps[30][30];
char Maps[30][30];  
int  MaxH[30][30];  
int  L[30],R[30];  
int  MUQ[30];  
  

int main()
{
	int T;
	scanf("%d",&T);getchar();
	for (int t = 1 ; t <= T ; ++ t) {
		scanf("%s",maps[0]);
		int n = strlen(maps[0]);
		for (int i = 1 ; i < n ; ++ i)
			scanf("%s",maps[i]);
		for (int i = 1 ; i <= n ; ++ i)
		for (int j = 1 ; j <= n ; ++ j)
			Maps[i][j] = maps[i-1][j-1];
		
		 //计算每条底边上的每列高度   
        memset(MaxH, 0, sizeof(MaxH));  
        for (int i = 1 ; i <= n ; ++ i)  
        for (int j = 1 ; j <= n ; ++ j)  
            if ( Maps[i][j] == '1' )  
                MaxH[i][j] = MaxH[i-1][j]+1;  
            else   
                MaxH[i][j] = 0;  
              
        for (int i = 1 ; i <= n ; ++ i)  
            MaxH[i][0] = MaxH[i][n+1] = -1;  
  
        int MaxV = 0;  
        for (int i = 1 ; i <= n ; ++ i) {  
            //计算每个点的左边界   
            int tail = 0;  
            MUQ[0] = 0;  
            for (int j = 1 ; j <= n+1 ; ++ j) {  
                while (tail >= 0 && MaxH[i][MUQ[tail]] > MaxH[i][j])  
                    R[MUQ[tail --]] = j;  
                MUQ[++ tail] = j;      
            }  
            //计算每个点的右边界   
                tail = 0;  
            MUQ[0] = n+1;  
            for (int j = n ; j >= 0 ; -- j) {  
                while (tail >= 0 && MaxH[i][MUQ[tail]] > MaxH[i][j])  
                    L[MUQ[tail --]] = j;  
                MUQ[++ tail] = j;      
            }  
            //求解  
            for (int j = 1 ; j <= n ; ++ j) {  
                int Temp = MaxH[i][j]*(R[j]-L[j]-1);  
                if (MaxV < Temp)  
                    MaxV = Temp;   
            }  
        } 
		printf("%d\n",MaxV);
		if (t < T) printf("\n"); 
	}
	
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来回答你的问题。 1. 求秩 使用 MATLAB 中的 rank 函数可以求出矩阵的秩: ``` A = [2 -2 0; -2 1 -2; 0 -2 0]; r = rank(A); disp(r); ``` 运行结果为: ``` r = 2 ``` 因此,矩阵 A 的秩为 2。 2. 求行最简型 使用 MATLAB 中的 rref 函数可以求出矩阵的行最简型: ``` A = [2 -2 0; -2 1 -2; 0 -2 0]; B = rref(A); disp(B); ``` 运行结果为: ``` B = 1.0000 0 1.0000 0 1.0000 1.0000 0 0 0 ``` 因此,矩阵 A 的行最简型为: ``` [ 1 0 1 ] [ 0 1 1 ] [ 0 0 0 ] ``` 3. 求行列式 使用 MATLAB 中的 det 函数可以求出矩阵的行列式: ``` A = [2 -2 0; -2 1 -2; 0 -2 0]; d = det(A); disp(d); ``` 运行结果为: ``` d = 0 ``` 因此,矩阵 A 的行列式为 0。 4. 求顺利主子式 顺利主子式是指从矩阵的左上角开始,每次增加一行一列得到的行列式。 使用 MATLAB 中的 submatrix 函数可以求出顺利主子式: ``` A = [2 -2 0; -2 1 -2; 0 -2 0]; d1 = det(A(1:1, 1:1)); d2 = det(A(1:2, 1:2)); d3 = det(A); disp([d1 d2 d3]); ``` 运行结果为: ``` d1 = 2 d2 = 2 d3 = 0 ``` 因此,矩阵 A 的顺利主子式为 2、2、0。 5. 求特征值及特征向量 使用 MATLAB 中的 eig 函数可以求出矩阵的特征值和特征向量: ``` A = [2 -2 0; -2 1 -2; 0 -2 0]; [V, D] = eig(A); disp(V); disp(D); ``` 运行结果为: ``` V = 0.7071 0.8165 0.4082 -0.0000 0.4082 -0.8165 -0.7071 0.4082 0.4082 D = -2.0000 0 0 0 0.0000 0 0 0 3.0000 ``` 因此,矩阵 A 的特征值为 -2、0、3,对应的特征向量为: ``` v1 = [0.7071; -0.0000; -0.7071] v2 = [0.8165; 0.4082; 0.4082] v3 = [0.4082; -0.8165; 0.4082] ``` 6. 求零空间 零空间是指矩阵 A 的所有零特征值所对应的特征向量的线性组合。 使用 MATLAB 中的 null 函数可以求出矩阵的零空间: ``` A = [2 -2 0; -2 1 -2; 0 -2 0]; N = null(A); disp(N); ``` 运行结果为: ``` N = -0.7071 -0.4082 0.0000 -0.8165 0.7071 -0.4082 ``` 因此,矩阵 A 的零空间为: ``` x = t * [-0.7071; 0; 0.7071] + s * [-0.4082; -0.8165; -0.4082] ``` 其中,t、s 为任意常数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值