BZOJ 1048 [HAOI2007]分割矩阵
1048: [HAOI2007]分割矩阵
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 623 Solved: 449
[Submit][Status][Discuss]
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
2 3 4 6
5 7 5 1
10 4 0 5
2 0 2 3
4 1 1 1
Sample Output
0.50
HINT
Source
题解:数据好小,显然记忆化爆搜即可喽。。。
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!注意!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!多维数组是不能用sizeof赋值的!!!!!!!!!!!!!!!!!!!
!!!啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<stack> 6 #include<queue> 7 #include<cstring> 8 #define PAU putchar(' ') 9 #define ENT putchar('\n') 10 using namespace std; 11 const int maxn=10+3,inf=-1u>>1; 12 double S[maxn][maxn],t[maxn][maxn][maxn][maxn][maxn],ve; 13 int n,m,k; 14 double sqr(double a){return a*a;} 15 double size(int x1,int y1,int x2,int y2){ 16 return S[x2][y2]+S[x1-1][y1-1]-S[x2][y1-1]-S[x1-1][y2]; 17 } 18 double dfs(int x1,int y1,int x2,int y2,int k){ 19 double&now=t[x1][y1][x2][y2][k]; 20 if(now!=-1)return now; 21 if(!k)return (now=sqr(size(x1,y1,x2,y2)-ve));now=1e9; 22 for(int i=x1;i<x2;i++) 23 for(int j=0;j<k;j++) 24 now=min(now,dfs(x1,y1,i,y2,j)+dfs(i+1,y1,x2,y2,k-j-1)); 25 for(int i=y1;i<y2;i++) 26 for(int j=0;j<k;j++) 27 now=min(now,dfs(x1,y1,x2,i,j)+dfs(x1,i+1,x2,y2,k-j-1)); 28 return now; 29 } 30 inline int read(){ 31 int x=0,sig=1;char ch=getchar(); 32 for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0; 33 for(;isdigit(ch);ch=getchar())x=10*x+ch-'0'; 34 return sig?x:-x; 35 } 36 inline void write(int x){ 37 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 38 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 39 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 40 } 41 int main(){ 42 n=read();m=read();k=read(); 43 for(int a=0;a<=10;a++) 44 for(int b=0;b<=10;b++) 45 for(int c=0;c<=10;c++) 46 for(int d=0;d<=10;d++) 47 for(int l=0;l<=10;l++) 48 t[a][b][c][d][l]=-1; 49 for(int i=1;i<=n;i++) 50 for(int j=1;j<=m;j++) 51 S[i][j]=S[i-1][j]+S[i][j-1]-S[i-1][j-1]+(double)read(); 52 ve=S[n][m]/k; 53 dfs(1,1,n,m,k-1); 54 printf("%.2lf",sqrt(t[1][1][n][m][k-1]/k)); 55 return 0; 56 } 57 /* 58 4 4 1 59 1 4 2 3 60 1 5 3 3 61 -1 6 3 3 62 2 5 2 1 63 1 1 2 3 64 */