暑假第四场积分赛——G题 colorful 二维动态数组dp+类前缀和处理

比赛网站http://net.hpuacm.cf/contests

题意

描述

Philo的周围一片黑暗。他踏出一步,脚下发出光亮。

该世界规则描述如下:这个世界建立在一个平面上,该平面由n*mn∗m个玻璃板组成,初始每块玻璃板都为熄灭状态且都可以被点亮,每一个玻璃板的边长是1。每一块玻璃板上都有一个数值xx,xx代表了这块玻璃板所发出光的亮度,每次点亮的方格必须是连续的,被点亮的方格可以被熄灭(你无须在意点亮和熄灭的细节,这对结果没有影响)。Philo可以从任意一个位置出发。

离开的条件是找到面积最大的一块正方形,该正方形内所有方格均被点亮,且该正方形上的每块玻璃板的亮度都大于kk(亮度可以相同)。

你的任务就是输出这个最大的面积。

0 < n,m\leq 2000,-1000\leq x,k \leq 10000<n,m≤2000,−1000≤x,k≤1000

输入

第一行输入nn,mm,kk 表示nn行mm列 kk表示要求大于的亮度。接下来是一个n*mn∗m的矩阵

输出

输出一个整数,即最大面积

输出一个整数,即最大面积

输入样例 1 

3 3 0
-1 1 -1
1 1 1
1 1 -1

输出样例 1

4

输入样例 2 

3 3 0
1 1 1
1 -1 1
1 1 1

输出样例 2

1

思路分析:

要想得出最大的正方形面积只要求出最大的正方形边长即可,对于正方形最大的边长可以用动态规划的思想来处理;

代码:

#include<bits/stdc++.h>

using namespace std;
const int maxn=2e3+5;
int dp[2][maxn];//dp[i][j]表示的是第i行第j列所能连成的最大长度,只不过i是二维滚动数组,并不是真实的i值,只有0和1
int n,x,m,k,ans;

int main()
{
	ios::sync_with_stdio(false);
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&x);
			ans=max(ans,dp[i&1][j]= x > k? min( dp[~i&1][j] , min( dp[~i&1][j-1] , dp[i&1][j-1] ) )+ 1 : 0);
//这里分别计算第i行和第j列左面和上面的所能连成的最大长度,然后再和它左上角的那个位置进行比较:::因为输入是从左上到右下,所以也是考虑左上方的正方形。
		}
	}
	cout<<ans*ans<<endl;
	return		0;
}

猜你喜欢

转载自blog.csdn.net/qq_41670466/article/details/81632191
今日推荐