【模拟】生日蛋糕(jzoj 1613)

版权声明:欢迎借鉴,谢绝抄搬。 https://blog.csdn.net/ssllyf/article/details/86614668

生日蛋糕

题目大意:

一个正方形蛋糕,竖着横着各切一刀,使他变成四块正方形蛋糕,蛋糕中有一些巧克力,而小明只能拿巧克力最少的一块,请问小明要怎么切才能吃到最多的巧克力

样例输入

8

…#…#…

.##…#…

…#.

.##…

…#.#…

…#.

…#…#…

样例输出

3

3 4

数据范围限制

提示

数据说明:

20% N<=50

50% N<=2000

100% N<=4500

解题思路:

用f[i][j]来表示前i行前j列的巧克力总数,那我们就可以得知:

f [ i ] [ j ] = f [ i 1 ] [ j ] + f [ i ] [ j 1 ] f [ i 1 ] [ j 1 ] + s f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+s

因为f[i-1][j]和f[i][j-1]重复了f[i-1][j-1]所以要减去,当此处有巧克力时,s为1否则为0

然后我们枚举1,1到n,n的每一个点,从这个点开始分割

左上为f[i][j],右上为f[i][n]-f[i][j],左下为f[n][j]-f[i][j],右下为f[n][n]-f[i][n]-f[n][j]+f[i][j],这四个之中最小的就是当前分法的结果,再求最大的结果,即可

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
int n,ans,f[4505][4505],t,x,y;
char c;
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=n;j++)
	    {
	    	f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1];//求f[i][j]
	    	cin>>c;//输入
	    	if(c=='#') f[i][j]++;//判断是否有巧克力
		}
	for (int i=1;i<=n;i++)
	 for (int j=1;j<=n;j++)
	   {
	   	t=min(min(f[i][j],f[i][n]-f[i][j]),min(f[n][j]-f[i][j],f[n][n]-f[i][n]-f[n][j]+f[i][j]));//记录下来
	   	if (t>=ans)//判断是否更优
	   	  {
	   	  	ans=t;//代替
	   	  	x=i;//记录
	   	  	y=j;//记录
		  }
	   }
	printf("%d\n%d %d",ans,x,y);//输出
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ssllyf/article/details/86614668
今日推荐