[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 }