比赛 2011.3.17 评测结果 AAAAAATTTT
题目名称 Brownie Slicing 最终得分 60
用户昵称 Pom 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-03-17 10:52:01
显示代码纯文本
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

const int MAXN=503;

int n,m,A,B,i,j,k,l;
int sum[MAXN][MAXN],F[MAXN][MAXN],f[MAXN][MAXN],w[MAXN][MAXN];

inline int cal(int x,int y)
{
	return sum[j][y]-sum[i-1][y]-sum[j][x-1]+sum[i-1][x-1];
}

int dp()
{
	int x,y,t,tmp;
	for (x=1;x<=B;x++)
	{
		t=x-1;
		for (y=x;y<=m-B+x;y++)
		{
			F[x][y]=0;
			if (x==1) F[x][y]=cal(1,y);
			else
				for (;;)
				{
					tmp=min(F[x-1][t],cal(t+1,y));
					if (tmp>=F[x][y])
					{
						F[x][y]=tmp;
						++t;
					}
					else 
					{
						--t;
						break;
					}
					if (t==y)
					{
						--t;
						break;
					}
				}
		}
	}
	return F[B][m];
}

int main()
{
	freopen("brownie.in","r",stdin);
	freopen("brownie.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&A,&B);
	for (i=1;i<=n;i++)
		for (j=1;j<=m;j++)
		{
			scanf("%d",&k);
			sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+k;
		}
	for (i=1;i<=n;i++)
		for (j=i;j<=n;j++)
			if (j-i+1<=n-A+1)
				w[i][j]=dp();
	int x,y,t,tmp;
	for (x=1;x<=A;x++)
	{
		t=x-1;
		for (y=x;y<=n-A+x;y++)
		{
			f[x][y]=0;
			if (x==1) f[x][y]=w[1][y];
			else
				for (;;)
				{
					tmp=min(f[x-1][t],w[t+1][y]);
					if (tmp>=f[x][y])
					{
						f[x][y]=tmp;
						++t;
					}
					else 
					{
						--t;
						break;
					}
					if (t==y)
					{
						--t;
						break;
					}
				}
		}
	}
	printf("%d\n",f[A][n]);
	return 0;
}