將乙個a*b的數字矩陣進行如下分割:將原矩陣沿某一條直線分割成兩個矩陣,再將生成的兩個矩陣繼續如此
分割(當然也可以只分割其中的乙個),這樣分割了(n-1)次後,原矩陣被分割成了n個矩陣。(每次分割都只能
沿著數字間的縫隙進行)原矩陣中每一位置上有乙個分值,乙個矩陣的總分為其所含各位置上分值之和。現在需要
把矩陣按上述規則分割成n個矩陣,並使各矩陣總分的均方差最小。請程式設計對給出的矩陣及n,求出均方差的最小值
。第一行為3個整數,表示a,b,n(1僅乙個數,為均方差
標準差的最小值(四捨五入精確到小數點後2位)
5 4 4
2 3 4 6
5 7 5 1
10 4 0 5
2 0 2 3
4 1 1 1
0.50
明明是標準差為什麼要寫方差!!!
a,b,n都那麼小,直接上$o(a^2b^2(a+b)n^2)$dp。。。
因為方差等於平方的期望減期望的平方(期望在這裡就是平均值),而後者是固定的(總和除以n),只需要求平方和最小即可。
定義$f_$為將上邊界為u,下邊界為d,左為l,右為r的矩陣切成k塊後的平方和最小是多少,那麼只需要列舉第一次從哪一行(或列)切和切成的兩半各分多少份即可。
狀態$o(a^2b^2n)$個,轉移$o(n(a+b))$。
簡單說,大概是$o(n^7)$的,如果a,b,n同階的話。
附**:
#include #include #include using std::min;typedef double ll;
const int n = 15;
ll s[n][n], f[n][n][n][n][n];
inline ll sqr(ll x)
inline ll sum(int l, int r, int u, int d)
int main()
for (int u = 1; u <= a; ++u)
for (int d = u; d <= a; ++d)
for (int l = 1; l <= b; ++l)
for (int r = l; r <= b; ++r)
f[1][u][d][l][r] = sqr(sum(l, r, u, d));
for (int k = 2; k <= n; ++k)
for (int hei = 1; hei <= a; ++hei)
for (int u = 1; u + hei - 1 <= a; ++u) }}
printf("%.2lf\n", sqrt(f[n][1][a][1][b] / n - sqr(s[a][b] / n)));
return 0;
}
bzoj1048 HAOI2007 分割矩陣
將乙個a b 的數字矩陣進行如下分割 將原矩陣沿某一條直線分割成兩個矩陣,再將生成的兩個矩陣繼續如此分割 當然也可以只分割其中的乙個 這樣分割了 n 1 次後,原矩陣被分割成了 n 個矩陣。每次分割都只能沿著數字間的縫隙進行 原矩陣中每一位置上有乙個分值,乙個矩陣的總分為其所含各位置上分值之和。現在...
BZOJ 1048 HAOI2007 分割矩陣
time limit 10 sec memory limit 162 mb submit 623 solved 449 submit status discuss 將乙個a b的數字矩陣進行如下分割 將原矩陣沿某一條直線分割成兩個矩陣,再將生成的兩個矩陣繼續如此分割 當然也可以只分割其中的乙個 這樣...
BZOJ1055 HAOI 玩具取名
某人有一套玩具,並想法給玩具命名。首先他選擇wing四個字母中的任意乙個字母作為玩具的基本名字。然後 他會根據自己的喜好,將名字中任意乙個字母用 wing 中任意兩個字母代替,使得自己的名字能夠擴充得很長。現在,他想請你猜猜某乙個很長的名字,最初可能是由哪幾個字母變形過來的。第一行四個整數w i n...