现在的位置: 首页 > 综合 > 正文

模拟赛 土豪聪要请客

2018年04月24日 ⁄ 综合 ⁄ 共 1208字 ⁄ 字号 评论关闭
文章目录

题目描述

众所周知,聪哥(ndsf)是个土豪,不过你们不知道的是他的MZ和他的RMB一样滴多……

   某天土豪聪又赚了10^10000e的RMB,他比较开心,于是准备请客。他在自己在XX星上的别墅里面大摆酒席,想要邀请尽可能多的MZ来参加他的宴会。他将会同MZ一起坐在一个巨大的长方形桌子上。这个桌子能坐下的人数等于他的边长。聪哥要求他的桌子能够放进他的别墅,并且桌子的边必须与别墅的边界平行。给定别墅的平面图,请你求出聪哥最多可以请多少个MZ。

输入格式

第一行n,m。表示别墅的长宽

下面n行,每行M个字符,表示一个方块是空的(‘ ’)或是被占用了(‘X’)。

聪哥只要他的桌子放在别墅里,并且桌子不能占用任何一个已经占用了的方块。

输出格式

一个数,表示聪哥最多可以请几个Maze。

样例输入1

2 2

..

..

样例输出1

7

样例输入2

4 4

X.XX

X..X

..X.

..XX

样例输出2

9

对于60%的数据,n,m<=100

对于100%的数据,n,m<=400

题解

一题怎么做都可以的动归,我是这样写的。s是每个点向上能到达的最长距离。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,a[405][405],s[405][405];
char ch[405]; 
int ans,f[405][405];
void init()
{
	scanf("%d%d",&n,&m);
	int i,j;
	for(j=1;j<=m;j++) a[0][j]=1;
	for(i=1;i<=n;i++)
	   {scanf("%s",ch+1);
	    for(j=1;j<=m;j++)
	       {if(ch[j]=='.') a[i][j]=1;
		    else a[i][j]=0;
		    if(a[i][j]==0) s[i][j]=0;
	        else s[i][j]=s[i-1][j]+1;
		   }
	   }
}
void dp()
{
	int i,j,k,maxs;
	for(i=1;i<=n;i++)
	for(j=1;j<=m;j++)
	   {if(a[i][j]==0) continue;
	    maxs=s[i][j]; f[i][j]=2*s[i][j]+1;
	    for(k=j;k>=1;k--)
	       {if(a[i][k]==0) break;
		    maxs=min(s[i][k],maxs);
			if(f[i][j]<((j-k+1)+maxs)*2-1) f[i][j]=((j-k+1)+maxs)*2-1;
			ans=max(f[i][j],ans);
		   }
	   }
	printf("%d\n",ans);
}
int main()
{
	freopen("stol.in","r",stdin);
	freopen("stol.out","w",stdout);
	init(); dp();
	return 0;
}

抱歉!评论已关闭.