• 悬线法 洛谷 P1387 最大正方形 P1681 最大正方形II P1736 创意吃鱼法


    P1387 最大正方形

    题意:一个01矩阵,求最大全1子矩阵边长

    核心dp方程:

        if(!area[i][j])continue;
    	f[i][j]=min(min(f[i][j-1],f[i-1][j]),f[i-1][j-1])+1;
    	ans=max(ans,f[i][j]);
    

    P1681 最大正方形II

    题意:求最大01交替的子矩阵边长

    可以开两个状态求解

    	scanf("%d",&area[i][j]);
    	if(area[i][j])
    		f[i][j][1]=min(min(f[i][j-1][0],f[i-1][j][0]),f[i-1][j-1][1])+1,ans=max(ans,f[i][j][1]);
    	if(!area[i][j])
    		f[i][j][0]=min(min(f[i][j-1][1],f[i-1][j][1]),f[i-1][j-1][0])+1,ans=max(ans,f[i][j][0]);
    

    P1736 创意吃鱼法

    题意:求最大对角线全1,其他全0的子矩阵边长

    注意分斜率为1和斜率为-1两种情况

    开个预处理

    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			if(area[i][j])lef[i][j]=0;
    			else lef[i][j]=lef[i][j-1]+1;
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=m;j>=1;j--){
    			if(area[i][j])rig[i][j]=0;
    			else rig[i][j]=rig[i][j+1]+1;
    		}
    	}
    	for(int j=1;j<=m;j++){
    		for(int i=1;i<=n;i++){
    			if(area[i][j])up[i][j]=0;
    			else up[i][j]=up[i-1][j]+1;
    		}
    	}
    
    

    之后的转移跟最大正方形几乎一样

    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			if(!area[i][j])continue;
    			f[i][j]=min(f[i-1][j-1],min(lef[i][j-1],up[i-1][j]))+1;
    			ans=max(f[i][j],ans);
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=m;j>=1;j--){
    			if(!area[i][j])continue;
    			f[i][j]=min(f[i-1][j+1],min(rig[i][j+1],up[i-1][j]))+1;
    			ans=max(f[i][j],ans);
    		}
    	}
    

    反而比最大正方形II好想

  • 相关阅读:
    单表查询
    阻塞非阻塞同步异步&异步回调
    基于协程的TCP并发编程
    协程
    死锁与递归锁
    线程池和进程池
    GIL全局解释器锁
    数据库——多表关系
    常用数据类型与约束
    Python基础(目录)
  • 原文地址:https://www.cnblogs.com/Y15BeTa/p/11832124.html
Copyright © 2020-2023  润新知