詳見**:
#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][10]; //
tot[m][n][i][j]記錄了左上角為m, n右下角為i, j的總和
/*題目是要求均方差的最小值,我們選擇對這個式子進行化簡,設均方差為t, 均值為u
t^2 = 1/n( sum(xi^2) - u^2 ) 又有 u = sum(xi)/n 可得出答案
因此只要每個部分的和值的平方最小就滿足條件了,也就是每一塊的和值最小
dp[k][m][n][i][j] 表示左上角為[m, n] 右下角為[i, j]一共有多少種分解方式
那麼這個分解方案就是由將這個[m][n][i][j]劃出一塊了作為第k塊,然後將剩下
的乙個矩形進行k-1次分割,所以說題目所說的那個剩下的乙個矩形也是非常有用的
當橫著切的時候
dp[k,m,n,i,j] = min(dp[k-1, m,a,i,j]+tot[m,n,i,a-1], dp[k-1, m,n,i,a-1]+tot[m,a,i,j]); n < a <= j
當豎著切的時候
dp[k,m,n,i,j] = min(dp[k-1, a,n,i,j]+tot[m,n,a-1,j], dp[k-1, m,n,a-1,j]+tot[a,n,i,j]); m < a <= i
*/void
dp()
//以下為縱向切割
for (int a = m+1; a <= i; ++a)
if (min != 0x7fffffff
) dp[k][m][n][i][j] =min;}}
}int
main()
}for (int i = 1; i <= 8; ++i)
for (int j = 1; j <= 8; ++j)
for (int m = 1; m <= i; ++m)
for (int n = 1; n <= j; ++n)
dp();
printf(
"%.3lf\n
", sqrt(double(n*dp[n-1][1][1][8][8]-tot[1][1][8][8])/(n*n)));
}return
0;
}
動態規劃 遞迴 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...
poj 1191 棋盤分割
棋盤分割 time limit 1000ms memory limit 10000k total submissions 10807 accepted 3798 description 將乙個 的棋盤進行如下分割 將原棋盤割下一塊矩形棋盤並使剩下部分也是矩形,再將剩下的部分繼續如此分割,這樣割了 n...
POJ 1191 棋盤分割
題意 給定一8 8的棋盤,每次沿著邊將棋盤切成兩部份,把一部分放到一邊,再繼續切另一部分,切n 1次得到n個矩形塊,問使n個塊的和能達到的最小方差。題解 顯然可以每次遍歷對矩形塊的橫切和豎切,當dfs到份數等於1,利用二維線段樹組將矩形塊的和求出來返回即可。剪枝 當訪問到同個矩形塊,相同切割份數時,...