1048: [HAOI2007]分割矩阵

Description

  将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此
分割(当然也可以只分割其中的一个),这样分割了(n-1)次后,原矩阵被分割成了n个矩阵。(每次分割都只能
沿着数字间的缝隙进行)原矩阵中每一位置上有一个分值,一个矩阵的总分为其所含各位置上分值之和。现在需要
把矩阵按上述规则分割成n个矩阵,并使各矩阵总分的均方差最小。请编程对给出的矩阵及n,求出均方差的最小值

Input

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

Output

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

Sample Input

5 4 4
2 3 4 6
5 7 5 1
10 4 0 5
2 0 2 3
4 1 1 1

Sample Output

0.50
 
 
矩阵这么小。。大暴力一下好了。。。首先求出平均值。。。然后矩阵用二维前缀和预处理。。
再来个记忆化搜索。。。
不过要注意精度。。。
 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<algorithm>
 7 #include<string>
 8 #include<map>
 9 #include<queue>
10 #include<vector>
11 #include<set>
12 #define inf 1000000000
13 #define maxn 15
14 #define maxm 10000+5
15 #define eps 1e-10
16 #define ll long long
17 #define for0(i,n) for(int i=0;i<=(n-1);i++)
18 #define for1(i,n) for(int i=1;i<=(n);i++)
19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
22 using namespace std;
23 int read(){
24     int x=0,f=1;char ch=getchar();
25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
27     return x*f;
28 }
29 int a[maxn][maxn],sum[maxn][maxn];
30 double ave;
31 double f[maxn][maxn][maxn][maxn][maxn];
32 double dfs(int a,int b,int c,int d,int k){
33     double &res=f[a][b][c][d][k];
34     if(res!=-1)return res;
35     if(k==0){
36         res=sum[b][d]+sum[a-1][c-1]-sum[b][c-1]-sum[a-1][d];
37         res=(res-ave)*(res-ave);
38         return res;
39     }
40     res=1e9;
41     for(int i=a+1;i<=b;i++)
42         for(int j=0;j<k;j++)
43             res=min(res,dfs(a,i-1,c,d,j)+dfs(i,b,c,d,k-j-1));
44     for(int i=c+1;i<=d;i++)
45         for(int j=0;j<k;j++)
46             res=min(res,dfs(a,b,c,i-1,j)+dfs(a,b,i,d,k-j-1));
47     return res;
48 }
49 int main(){
50     //freopen("input.txt","r",stdin);
51     //freopen("output.txt","w",stdout);
52     int n=read(),m=read(),t=read();
53     for0(i,maxn)
54         for0(j,maxn)
55             for0(k,maxn)
56                 for0(r,maxn)
57                     for0(l,maxn)
58                         f[i][j][k][r][l]=-1;
59     for1(i,n)
60         for1(j,m)
61             a[i][j]=read();
62     for1(i,n)
63         for1(j,m)
64             sum[i][j]=sum[i-1][j]+sum[i][j-1]+a[i][j]-sum[i-1][j-1];
65     ave=(double)sum[n][m]/t;
66     dfs(1,n,1,m,t-1);
67     printf("%.2lf",sqrt(f[1][n][1][m][t-1]/t));
68     return 0;
69 }
View Code

 

posted @ 2016-05-19 17:35  HTWX  阅读(235)  评论(0编辑  收藏  举报