POJ 1191

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
int n,a[9][9];
int f[9][9][9][9][16],pre[9][9];
int dp(int x1,int y1,int x2,int y2,int k)
{
	if(k==0)
	f[x1][y1][x2][y2][k]=(pre[x2][y2]-pre[x2][y1-1]-pre[x1-1][y2]+pre[x1-1][y1-1])*(pre[x2][y2]-pre[x2][y1-1]-pre[x1-1][y2]+pre[x1-1][y1-1]);
	if(x1==x2&&y1==y2)f[x1][y1][x2][y2][k]=a[x1][y1]*a[x1][y1];
	if(f[x1][y1][x2][y2][k]<0x3f3f3f3f)return f[x1][y1][x2][y2][k];
	for(int i=x1;i<x2;i++)
	{
		f[x1][y1][x2][y2][k]=min(f[x1][y1][x2][y2][k],dp(x1,y1,i,y2,0)+dp(i+1,y1,x2,y2,k-1));
		f[x1][y1][x2][y2][k]=min(f[x1][y1][x2][y2][k],dp(x1,y1,i,y2,k-1)+dp(i+1,y1,x2,y2,0));
	}
	for(int i=y1;i<y2;i++)
	{
		f[x1][y1][x2][y2][k]=min(f[x1][y1][x2][y2][k],dp(x1,y1,x2,i,0)+dp(x1,i+1,x2,y2,k-1));
		f[x1][y1][x2][y2][k]=min(f[x1][y1][x2][y2][k],dp(x1,y1,x2,i,k-1)+dp(x1,i+1,x2,y2,0));
	}
	return f[x1][y1][x2][y2][k];
}
int main()
{
	while(~scanf("%d",&n))
	{
		memset(pre,0,sizeof(pre));
		memset(f,0x3f,sizeof(f));
		for(int i=1;i<=8;i++)
		{
			for(int j=1;j<=8;j++)
			{
				scanf("%d",&a[i][j]);
				pre[i][j]=pre[i][j-1]+pre[i-1][j]-pre[i-1][j-1]+a[i][j];
 
			}
		}
		printf("%.3lf\n",sqrt(dp(1,1,8,8,n-1)*1.0/n-(1.0*pre[8][8]/n)*(1.0*pre[8][8]/n)));
	}
	return 0;
}