将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,
再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘。
(每次切割都只能沿着棋盘格子的边进行)
原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。
现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。
均方差,其中平均值,xi为第i块矩形棋盘的总分。
请编程对给出的棋盘及n,求出O‘的最小值。
#include <iostream> #include <cstring> #include <cmath> #include <iomanip> #include <fstream> using namespace std; const int MAX = 1 << 30; int chessboard[9][9]; int sums[9][9][9][9]; double DP[20][9][9][9][9]; int N; int main(){ double totals = 0.0; double avg = 0.0; memset( chessboard, 0, sizeof( chessboard ) ); memset( sums, 0, sizeof( sums ) ); //fstream fin( "test.txt" ); cin >> N; for( int i = 1; i <= 8; ++i ){ for( int j = 1; j <= 8; ++j ){ cin >> chessboard[i][j]; sums[i][j][i][j] = chessboard[i][j]; totals += chessboard[i][j]; chessboard[i][j] += chessboard[i - 1][j] + chessboard[i][j - 1] - chessboard[i - 1][j - 1]; } } avg = totals / ( N * 1.0 ); for( int x1 = 1; x1 <= 8; ++x1 ){ for( int y1 = 1; y1 <= 8; ++y1 ){ for( int x2 = x1; x2 <= 8; ++x2 ){ for( int y2 = y1; y2 <= 8; ++y2 ){ sums[x1][y1][x2][y2] = chessboard[x2][y2] - chessboard[x1 - 1][y2] - chessboard[x2][y1 - 1] + chessboard[x1 - 1][y1 - 1]; DP[0][x1][y1][x2][y2] = sums[x1][y1][x2][y2] * sums[x1][y1][x2][y2]; } } } } for( int k = 1; k <= N - 1; ++k ){ for( int x1 = 1; x1 <= 8; ++x1 ){ for( int y1 = 1; y1 <= 8; ++y1 ){ for( int x2 = x1; x2 <= 8; ++x2 ){ for( int y2 = y1; y2 <= 8; ++y2 ){ DP[k][x1][y1][x2][y2] = MAX; for ( int mid = x1; mid < x2; ++mid ){ DP[k][x1][y1][x2][y2] = min( DP[k][x1][y1][x2][y2], DP[0][x1][y1][mid][y2] + DP[k - 1][mid + 1][y1][x2][y2] ); DP[k][x1][y1][x2][y2] = min( DP[k][x1][y1][x2][y2], DP[k - 1][x1][y1][mid][y2] + DP[0][mid + 1][y1][x2][y2] ); } for( int mid = y1; mid < y2; ++mid ){ DP[k][x1][y1][x2][y2] = min( DP[k][x1][y1][x2][y2], DP[0][x1][y1][x2][mid] + DP[k - 1][x1][mid + 1][x2][y2] ); DP[k][x1][y1][x2][y2] = min( DP[k][x1][y1][x2][y2], DP[k - 1][x1][y1][x2][mid] + DP[0][x1][mid + 1][x2][y2] ); } } } } } } double ans = DP[N - 1][1][1][8][8] / ( N * 1.0 ) - avg * avg; cout << setprecision(3) << fixed << sqrt(ans) << endl; return 0; }
时间: 2024-10-15 07:57:01