生日蛋糕
题目大意:
一个正方形蛋糕,竖着横着各切一刀,使他变成四块正方形蛋糕,蛋糕中有一些巧克力,而小明只能拿巧克力最少的一块,请问小明要怎么切才能吃到最多的巧克力
样例输入
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]+sf[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+sf[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];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;
}