这个题是DP+DFS,DP比较简单吧,只要想到的话应该就不难了,注意状态的记录就可以了(状态记录需要加上现在的层数)
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
int n;
double ans,ave;
double dp[16][9][9][9][9],map[9][9];
double DFS(int now,int rowa,int rowb,int cola,int colb)
{
if(dp[now][rowa][rowb][cola][colb])
return dp[now][rowa][rowb][cola][colb];
double sum;
if(now==n-1)
{
sum=0;
for(int i=rowa;i<rowb;i++)
for(int j=cola;j<colb;j++)
sum+=map[i][j];
return (sum-ave)*(sum-ave);
}
double mins=0xfffffffffffffff;
for(int i=rowa+1;i<rowb;i++)
{
sum=0;
for(int j=rowa;j<i;j++)
for(int k=cola;k<colb;k++)
sum+=map[j][k];
mins=min(mins,DFS(now+1,i,rowb,cola,colb)+(sum-ave)*(sum-ave));
sum=0;
for(int j=i;j<rowb;j++)
for(int k=cola;k<colb;k++)
sum+=map[j][k];
mins=min(mins,DFS(now+1,rowa,i,cola,colb)+(sum-ave)*(sum-ave));
}
for(int i=cola+1;i<colb;i++)
{
sum=0;
for(int j=rowa;j<rowb;j++)
for(int k=cola;k<i;k++)
sum+=map[j][k];
mins=min(mins,DFS(now+1,rowa,rowb,i,colb)+(sum-ave)*(sum-ave));
sum=0;
for(int j=rowa;j<rowb;j++)
for(int k=i;k<colb;k++)
sum+=map[j][k];
mins=min(mins,DFS(now+1,rowa,rowb,cola,i)+(sum-ave)*(sum-ave));
}
dp[now][rowa][rowb][cola][colb]=mins;
return mins;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(dp,0,sizeof(dp));
double sum=0;
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
{
scanf("%lf",&map[i][j]);
sum+=map[i][j];
}
ave=sum/n;
printf("%.3f\n",sqrt(DFS(0,0,8,0,8)/n));
}
return 0;
}