BZOJ 1048 [HAOI2007]分割矩阵

1048: [HAOI2007]分割矩阵

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 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

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 */
时间: 2024-10-02 18:22:19

BZOJ 1048 [HAOI2007]分割矩阵的相关文章

[BZOJ 1048] [HAOI2007] 分割矩阵 【记忆化搜索】

题目链接:BZOJ - 1048 题目分析 感觉这种分割矩阵之类的题目很多都是这样子的. 方差中用到的平均数是可以直接算出来的,然后记忆化搜索 Solve(x, xx, y, yy, k) 表示横坐标范围 [x, xx], 纵坐标范围 [y, yy] 的矩阵切成 k 块的最小 sigma((Vi - Ave)^2) . 然后再递归将矩阵分得更小,直到 k 为 1 的时候直接返回相应的值. 代码 #include <iostream> #include <cstdlib> #incl

【BZOJ】1048: [HAOI2007]分割矩阵

http://www.lydsy.com/JudgeOnline/problem.php?id=1048 给出一个a×b(a,b<=10)的矩阵,带一个<=100的权值,现在要切割n-1次变成n个矩形(n<=10),求 $$\sqrt{\frac{1}{n}\sum_{i=1}^{n}(sum[i]-\mu)}, \mu = \frac{\sum_{i=1}^{n} sum[i]}{n}, sum[i]表示矩阵的和$$ 的最小值 #include <cstdio> #incl

1048: [HAOI2007]分割矩阵

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1184  Solved: 863[Submit][Status][Discuss] Description 将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此分割(当然也可以只分割其中的一个),这样分割了(n-1)次后,原矩阵被分割成了n个矩阵.(每次分割都只能沿着数字间的缝隙进行)原矩阵中每一位置上有一个分值,一个矩阵的总分为其所含各位置上分值之和.

1048: [HAOI2007]分割矩阵——记忆化搜索

http://www.lydsy.com/JudgeOnline/problem.php?id=1048 TML了一发 #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #define clr(a,b) memset(a,b,sizeof(a)) const double INF = 0x3f3f3f3f;

【BZOJ 1048】 [HAOI2007]分割矩阵

1048: [HAOI2007]分割矩阵 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 498  Solved: 362 [Submit][Status] Description 将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此分割(当然也可以只分割其中的一个),这样分割了(n-1)次后,原矩阵被分割成了n个矩阵.(每次分割都只能沿着数字间的缝隙进行)原矩阵中每一位置上有一个分值,一个矩阵的总分

BZOJ-1048: [HAOI2007]分割矩阵 (记忆化搜索)

1048: [HAOI2007]分割矩阵 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1040  Solved: 751[Submit][Status][Discuss] Description 将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此分割(当然也可以只分割其中的一个),这样分割了(n-1)次后,原矩阵被分割成了n个矩阵.(每次分割都只能沿着数字间的缝隙进行)原矩阵中每一位置上有一个分值

BZOJ1048: [HAOI2007]分割矩阵

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1048 题解:搞清题意之后来个记忆化爆搜就行了. 代码: 1 #include<cstdio> 2 3 #include<cstdlib> 4 5 #include<cmath> 6 7 #include<cstring> 8 9 #include<algorithm> 10 11 #include<iostream> 12 13

P2217 [HAOI2007]分割矩阵

传送门 首先均方差公式: $\sigma = \sqrt{\sum_{i}^{K}\frac{(sum[i]-\bar{sum})^2}{n}}$ 其中 $\bar{sum}$ 为小矩阵的平均值,显然 $\bar{sum}=\frac{\sum_{i}^{K}sum[i]}{K}$ 所以就是要最小化 $(sum[i]-\bar{sum})^2$ 看到数据这么小,搜就完事了 直接 $dfs(xa,ya,xb,yb,k)$ 表示以 $(xa,ya)$ 为左下角,$(xb,yb)$ 为右上角的子矩阵内

【BZOJ】【1048】【HAOI2007】分割矩阵

DP/记忆化搜索 暴力枚举分割方案?……大概是指数级的?大约是20!的方案= =? 但是我们看到a.b.n的范围都很小……所以不同的状态数只是$10^5$级别的,可以记忆化搜索求解 比较水的一道题…… 1 /************************************************************** 2 Problem: 1048 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:132 ms 7 Me