棋盤分割 維數較大的動態規劃

2022-05-02 11:42:09 字數 1908 閱讀 1196

一、問題描述

將乙個8*8的棋盤進行如下分割:將原棋盤割下一塊矩形棋盤並使剩下部分也是矩形,再將剩下的部分繼續如此分割,這樣割了(n-1)次後,連同最後剩下的矩形棋盤共有n塊矩形棋盤。(每次切割都只能沿著棋盤格仔的邊進行)

原棋盤上每一格有乙個分值(小於100的非負整數),一塊矩形棋盤的總分為其所含各格分值之和。現在需要把棋盤按上述規則分割成n塊矩形棋盤,並使各矩形棋盤總分的均方差最小。 (1 < n < 15)

二、解題思路 / n

σ = √∑(xi- x) 2/ n,x = ∑xi / n 

x為平均值,把不管如何切割,已經確定了。

我們把標準差公式變形(只考慮根號內):

∑(xi- x) 2/ n = ∑(xi

2 + x2 - 2*xi*x) / n

=( ∑xi

2 + ∑x2 - 2*x*∑xi ) / n

= ( ∑xi

2 + n*x2 - 2*x*nx) / n

= ∑xi

2 / n - x2

所以求標準差的最小值,等價於求平方和的最小值。

用d[k][x1][x2][y1][y2]表示1--x2,y1--y2圍成的矩形切割k次平方和的最小值

橫著切:d[k - 1][x1][a][y1][y2] + sum[a + 1][x2][y1][y2](選上邊,加下邊)

d[k - 1][a + 1][x2][y1][y2] + sum[x1][a][y1][y2](選下邊,加上邊)

豎著切: d[k - 1][x1][x2][y1][b] + sum[x1][x2][b + 1][y2](選右邊,加左邊)

d[k - 1][x1][x2][b + 1][y2] + sum[x1][x2][y1][b](選左邊,加右邊)

k作為階段,初始化k ==0 的情況,即未切,易知d[0][x1][x2][y1][y2] = sum[x1][x2][y1][y2],k從小到大遞推,d[n - 1][0][7][0][7]就是n個塊平方和的最大值。

三、**實現

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;78

const

int inf = 0x3f3f3f3f;9

intn;

10int arr[10][10

];11

int sum[10][10][10][10]; //

sum[x1][x2][y1][y2]表示x1--x2,y1--y2圍成矩形的面積

12int d[20][10][10][10][10]; //

d[k][x1][x2][y1][y2]表示1--x2,y1--y2圍成的矩形切割k次平方和的最小值

1314

void

init()

1527}28

29void

slove()

3050}51

52double res = sqrt((double)d[n - 1][0][7][0][7] / n - (double)sum[0][7][0][7] / ((double)n * n)); //

注意開根號,血的教訓啊

53 printf("

%.3lf\n

",res );54}

5556

intmain()

5765 }

四、總結

準確的說,這還是我第一次對數學公式進行化簡求解問題,可見數學歸納、再化簡是解決問題的一種重要方法。

同時,這也是我第一次做三維以上的動態規劃題(雖然與二維三維沒多大區別,但也客服了一點心理恐懼),再次使用遞推解決問題,而不是記憶化搜尋,進一步加深了我對「階段」,也就是各維迴圈順序的理解。

Luogu1436 棋盤分割(動態規劃)

無 將乙個 的棋盤進行如下分割 將原棋盤割下一塊矩形棋盤並使剩下部分也是矩形,再將剩下的兩部分中的任意一塊繼續如此分割,這樣割了 n 1 次後,連同最後剩下的矩形棋盤共有n塊矩形棋盤。每次切割都只能沿著棋盤格仔的邊進行 原棋盤上每一格有乙個分值,一塊矩形棋盤的總分為其所含各格分值之和。現在需要把棋盤...

POJ 1191 棋盤分割 動態規劃

詳見 include include include include include include using namespace std int n,sum 10 10 sum i j 表示以i,j為右下角的矩陣的和 int dp 15 10 10 10 10 int tot 10 10 10 ...

動態規劃 遞迴 poj1191,棋盤分割

明白幾點 1 最終的均方差 2 動歸含義 dp n x1 x2 y1 y2 表示由x1,x2,y1,y2組成的矩形要生成n塊小矩陣,均方差的最小值 sigma i 1 m xi xi 它的值需要遍歷所有橫向切 縱向切的可能,然後取最小值。最終結果是dp n 1 8 1 8 不多說。include i...