首页 > 其他分享 >题解 UVA12265【贩卖土地 Selling Land】

题解 UVA12265【贩卖土地 Selling Land】

时间:2022-11-15 17:44:06浏览次数:83  
标签:5010 Land int 题解 top us leq Selling las

posted on 2022-09-24 14:33:29 | under 题解 | source

problem

一个黑白矩阵,求以每个点为右下角,能围出的周长最大的全白矩形的周长。\(n\leq 2000\)。

solution

试图进行线性 DP,令 \(f_{i,j}\) 表示以 \((i,j)\) 为右下角的答案。

尝试从 \(f_{i-1,j},f_{i,j-1}\) 转移到 \(f_{i,j}\),但是以一个点为右下角的空矩阵有很多,不能全部存下来,怎么办呢?那就不要存了。

换一种思路,我们从一行的角度看它,举个例子:

land.png

从点 \((i,j)\) 一直往左走,底下那条边(称为宽)越长,能往上延伸出的长度(称为高)越矮。更形式化地说,令 \(g_{i,j}\) 为点 \((i,j)\) 往上有多少块空地,那我们可以枚举一个宽 \(len\),对应的高就是 \(\min\limits_{i-len<j\leq i}\{g_{i,j}\}\),那么点 \((i,r)\) 的答案就是:(变量含义有变化)

\[ans_{i,r}=\max_{l}\{\min_{l\leq j\leq r}\{g_{i,j}\}+r-l+1\} \]

从这里分出两种理解方式:

代数

将 \(r+1\) 丢出去:

\[ans_{i,r}=\max_{1\leq l\leq r}\{\min_{l\leq j\leq r}\{g_{i,j}\}-l\}+r+1 \]

我们令 \(las_{i,r}\) 为一个最大的 \(k\) 使得 \(g_{i,k}<g_{i,r}\),把 \(l\) 的枚举范围 \([1,r]\) 分成两部分:

  • \([las_{i,r}+1,r]\):显然这一部分总是 \(g_{i,r}-l\)。
  • \([1,las_{i,r}]\):写出来就是 \(\max_{1\leq l\leq las_{i,r}}\{\min_{l\leq j\leq las_{i,r}}\{g_{i,j}\}-l\}\),非常感动,这是 \(ans_{i,las_{i,r}}\) 求过的东西,于是直接拿过来用。

已经做完了。

几何

land.png

(求以红色方块为右下角的答案,橙色不能踩)

可以把那条绿线看成一种类似轮廓线的东西,我们只需要维护轮廓线底下这些棕色矩形就可以了。容易发现轮廓线是单调不降的,因此我们可以用一个单调栈维护这条线的折角处,顺带维护栈中的最大值(连着折角一起放入栈,一起弹出栈)就可以了。

code

//lock /kk
#include <cstdio>
#include <cstring>
#include <utility>
#include <algorithm>
using namespace std;
int n,m;
char a[5010][5010];
int us[5010][5010],ret[100010];
int stk[5010],mx[5010];
void dp(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[i][j]=='.'){
				us[i][j]=us[i-1][j]+1;
			}
		}
	}
	int top=0;
	mx[0]=-1e9;
	for(int i=1;i<=n;i++){
		stk[top=0]=0;
		for(int j=1;j<=m;j++){
			if(a[i][j]=='#') stk[top=0]=j;
			else{
				while(top&&us[i][stk[top]]>=us[i][j]) top--;
				stk[++top]=j;
				mx[top]=max(mx[top-1],us[i][j]-stk[top-1]);
				ret[mx[top]+j]++;
			}
		}
	}
}
int mian(){
//	freopen("run.in","r",stdin);
//	freopen("run.out","w",stdout);
	memset(us,0,sizeof us);
	memset(ret,0,sizeof ret);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
	dp();
	for(int i=1;i<=n+m;i++){
		if(ret[i]) printf("%d x %d\n",ret[i],i*2);
	}
	return 0;
}
int main(){
	for(scanf("%*d");~scanf("%d%d",&n,&m);mian());
	return 0;
}

标签:5010,Land,int,题解,top,us,leq,Selling,las
From: https://www.cnblogs.com/caijianhong/p/solution-UVA12265.html

相关文章

  • 焦点科技编程挑战赛2022题解
    比赛说明:比赛在四个学校开展,南理南航南农和矿大。题目查找文本差异要求origin和dest中分别包含1000w+条数据dest对数据进行了打乱操作,即origin和dest中相同数据行的......
  • CF1598F RBS 题解
    题意给\(n\)个串,求将这\(n\)个串以任意顺序接起来的最大的是合法括号序列的前缀数。分析\(n\)很小,考虑状压dp。有一个很典的转化是将(看成\(+1\),将)看成\(-......
  • CF 1743 题解
    比赛链接:https://codeforces.com/contest/1743题解:AB水题//bySkyRainWind#include<cstdio>#include<vector>#include<cstring>#include<iostream>#include......
  • week3题解
    1.寄包柜   看到题目最容易想到开二位数组但数据量过大,因此需要map#include<bits/stdc++.h>usingnamespacestd;map<int,map<int,int>>a;这里开了一个map......
  • el-date-picker 等 点击无反应不回显问题解决
    参考链接:https://blog.csdn.net/QQ2856639881/article/details/116918081?spm=1001.2101.3001.6661.1&depth_1-utm_relevant_index=1最近在做一个动态表单回显。数据嵌套......
  • vue项目中eslint报“Missing space before function parentheses”的问题解决
    原文链接:https://blog.csdn.net/u011523953/article/details/1067718681、问题原因:使用eslint时,严格模式下,报错Missingspacebeforefunctionparentheses(函数括号前缺少......
  • 【题解】CF1748D ConstructOR
    前言这道题十分诈骗,比赛的时候以为是根据二进制除法原理,解同余方程,然后考试时候就没做出来QAQ。这篇题解是构造解法,至于官方题解是啥我也不知道,看这官方题解的性质十分诡......
  • P8816 [CSP-J 2022] 上升点列 题解
    题目传送门:luoguP8816[CSP-J2022]上升点列这是一道简单的dp题。定义到达指两点的曼哈顿距离是\(1\)。我们考虑设状态\(f(i,j)\)表示考虑结尾是第\(i\)个点,增......
  • P6406 [COCI2014-2015#2] Norma 题解
    前言洛谷上很多大佬都写的CDQ分治的解法。但看了某篇大佬的线段树解法,受益匪浅,于是决定写一篇题解来记录一下这种解法。前置知识:单调栈,线段树题目通道题目描述给......
  • CF1743F Intersection and Union 题解
    更好体验线段的贡献不好统计,考虑统计每一个点在不同情况中的被覆盖次数,那么每个点的被覆盖次数总和即为答案。设\(f_{i,j,0/1}\)表示\(i\)点在扫描到线段\(j\)时是......