將乙個8*8的棋盤進行如下分割:將原棋盤割下一塊矩形棋盤並使剩下部分也是矩形,再將剩下的部分繼續如此分割,這樣割了(n-1)次後,連同最後剩下的矩形棋盤共有n塊矩形棋盤。(每次切割都只能沿著棋盤格仔的邊進行)
原棋盤上每一格有乙個分值,一塊矩形棋盤的總分為其所含各格分值之和。現在需要把棋盤按上述規則分割成n塊矩形棋盤,並使各矩形棋盤總分的均方差最小。
均方差請程式設計對給出的棋盤及n,求出o'的最小值。
input
第1行為乙個整數n(1 < n < 15)。
第2行至第9行每行為8個小於100的非負整數,表示棋盤上相應格仔的分值。每行相鄰兩數之間用乙個空格分隔。
output
僅乙個數,為o'(四捨五入精確到小數點後三位)。
sample input
3
1 1 1 1 1 1 1 3
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 3
sample output
1.633
題解:設dp[y1][x1][y2][x2][k]dp[y1][x1][y2][x2][k]表示切了k次後左上角座標為(y1,x1)(y1,x1),右下角座標為(y2,x2)(y2,x2)的矩形當前∑ki=1x2i∑i=1kxi2的最小值。
則有四種轉移始狀態,為當前矩形為從某(上/下/左/右)側切一整塊,另一側為k−1k−1個分割完的塊。
#include #include #include #include using namespace std;
int ma[9][9];
int n;
int sum[9][9][9][9];
int dp[16][9][9][9][9];
void init()
}int dp(int k,int x,int y,int xx,int yy)
for(int i=y; i<=yy; i++)
return dp[k][x][y][xx][yy];
}int main()
}init();
memset(dp,-1,sizeof(dp));
dp(0,0,0,7,7);
ans=sqrt(dp[0][0][0][7][7]*1.0/n-(cnt*1.0)/n*(cnt*1.0)/n);
printf("%.3f\n",ans);
return 0;
}
遞迴 棋盤分割問題
language default 棋盤分割 time limit 1000ms memory limit 10000k total submissions 11819 accepted 4175 description 將乙個 的棋盤進行如下分割 將原棋盤割下一塊矩形棋盤並使剩下部分也是矩形,再將剩...
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,利用二維線段樹組將矩形塊的和求出來返回即可。剪枝 當訪問到同個矩形塊,相同切割份數時,...