[HAOI2007]分割矩阵

题目描述

将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此分割(当然也可以只分割其中的一个),这样分割了(n-1)次后,原矩阵被分割成了n个矩阵。(每次分割都只能沿着数字间的缝隙进行)

原矩阵中每一位置上有一个分值,一个矩阵的总分为其所含各位置上分值之和。现在需要把矩阵按上述规则分割成n个矩阵,并使各矩阵总分的均方差最小。

请编程对给出的矩阵及n,求出均方差的最小值。

输入输出格式

输入格式:

第一行为3个整数,表示a,b,n(1<a,b<=10,1<n<=10)的值。

第二行至第n+1行每行为b个小于100的非负整数,表示矩阵中相应位置上的分值。每行相邻两数之间用一个空格分开。

输出格式:

仅一个数,为均方差的最小值(四舍五入精确到小数点后2位)

输入输出样例

输入样例#1: 复制
输出样例#1: 复制
为了防止超时,用记忆化
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 double ave,a[11][11],sum[11][11],f[11][11][11][11][11];
 8 int n,m;
 9 double dfs(int x1,int y1,int x2,int y2,int k)
10 {int i,j;
11   if (f[x1][y1][x2][y2][k]!=-1) return f[x1][y1][x2][y2][k];
12   double ans=2e9;
13   double x=sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];
14   if (k==0) return (x-ave)*(x-ave);
15   for (i=x1+1;i<=x2;i++)
16     for (j=0;j<k;j++)
17     {
18       ans=min(ans,dfs(x1,y1,i-1,y2,j)+dfs(i,y1,x2,y2,k-j-1));
19     }
20   for (i=y1+1;i<=y2;i++)
21     for (j=0;j<k;j++)
22     {
23       ans=min(ans,dfs(x1,y1,x2,i-1,j)+dfs(x1,i,x2,y2,k-j-1));
24     }
25   return f[x1][y1][x2][y2][k]=ans;
26 }
27 int main()
28 {int i,j,k,x,y,l;
29   cin>>n>>m>>k;
30   memset(f,-1,sizeof(f));
31   for (i=1;i<=n;i++)
32     {
33       for (j=1;j<=m;j++)
34     {
35       scanf("%lf",&a[i][j]);
36       sum[i][j]=a[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
37     }
38     }
39   ave=sum[n][m]/(double)k;
40   dfs(1,1,n,m,k-1);
41   printf("%.2lf\n",sqrt(f[1][1][n][m][k-1]/(double)k));
42 }

 

posted @ 2018-02-28 16:31  Z-Y-Y-S  阅读(482)  评论(0编辑  收藏  举报