比赛 2011.3.17 评测结果 AAAAAAATTT
题目名称 Brownie Slicing 最终得分 70
用户昵称 苏轼 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-03-17 11:29:07
显示代码纯文本
#include <cstdio>
#include <algorithm>
using namespace std;

const int MAXN=505;
int oo;

int R,C,A,B;
int a[MAXN][MAXN];
int sum[MAXN][MAXN];

int s[MAXN];
inline bool judge(int mid)
{
	int div=0,tot=0;
	for(int k=1;k<=C;k++)
	{
		tot+=s[k];
		if (tot>=mid)
		{
			div++;
			tot=0;
			if (div>=B)
				return true;
		}
	}
	return false;
}

int d[MAXN][MAXN],f[MAXN][MAXN];
int main()
{
	freopen("brownie.in","r",stdin);
	freopen("brownie.out","w",stdout);
	scanf("%d%d%d%d",&R,&C,&A,&B);
	for(int i=1;i<=R;i++)
		for(int j=1;j<=C;j++)
		{
			scanf("%d",a[i]+j);
			oo+=a[i][j];
		}
	for(int i=1;i<=C;i++)
		for(int j=1;j<=R;j++)
			sum[i][j]=sum[i][j-1]+a[j][i];
	for(int i=1;i<=R;i++)
		for(int j=i;j<=R;j++)
		{
			for(int k=1;k<=C;k++)
				s[k]=sum[k][j]-sum[k][i-1];	
			int l=0,r=oo;
			while(l+1<r)
			{
				int mid=((long long)(l)+r)/2;
				if (judge(mid)) l=mid;
				else r=mid;
			}
			if (l==r) f[i][j]=l;
			else if (judge(r)) f[i][j]=r;
			else f[i][j]=l;
		}
	for(int i=1;i<=R;i++)
		d[i][1]=f[1][i];
	for(int j=2;j<=A;j++)
		for(int i=j;i<=R;i++)
			for(int k=j;k<=i;k++)
				d[i][j]=max(d[i][j],min(d[k-1][j-1],f[k][i]));
	printf("%d\n",d[R][A]);
	return 0;
}