無
將乙個8*8的棋盤進行如下分割:將原棋盤割下一塊矩形棋盤並使剩下部分也是矩形,再將剩下的兩部分中的任意一塊繼續如此分割,這樣割了(n-1)次後,連同最後剩下的矩形棋盤共有n塊矩形棋盤。(每次切割都只能沿著棋盤格仔的邊進行)
原棋盤上每一格有乙個分值,一塊矩形棋盤的總分為其所含各格分值之和。現在需要把棋盤按上述規則分割成n塊矩形棋盤,並使各矩形棋盤總分的平方和最小。
請程式設計對給出的棋盤及n,求出平方和的最小值。
第1行為乙個整數n(1 < n < 15)。
第2行至第9行每行為8個小於100的非負整數,表示棋盤上相應格仔的分值。每行相鄰兩數之間用乙個空格分隔。
僅乙個數,為平方和。
輸入 #1
3輸出 #11 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
1460嗯,看資料範圍這麼小,肯定搞一堆迴圈暴力dp。
推式子應該不是太難,設dp[k][i][j][p][q]表示從(i,j)到(p,q)中分成k個矩形最小的平方和。
那麼初始化就是dp[1][i][j][p][q]=sum(i,j,p,q)^2
至於,sum可以用乙個二維字首和的預處理搞。
考慮一下具體的dp轉移過程:
再列舉乙個t,表示把i到p行從t行這個分成兩塊,一塊分一次,一塊分k-1次,
也表示把j到q列從t列分成兩塊,一塊分一次,一塊分k-1次
那麼整個方程就很清晰了:
chkmin(dp[tk][i][j][p][q],min(dp[tk-1][i][j][t-1][q]+dp[1][t][j][p][q],dp[1][i][j][t-1][q]+dp[tk-1][t][j][p][q]));
chkmin(dp[tk][i][j][p][q],min(dp[tk-1][i][j][p][t-1]+dp[1][i][t][p][q],dp[1][i][j][p][t-1]+dp[tk-1][i][t][p][q]));
**:
#include#include#include#include#includeusing namespace std;const int n=8;
int n=8,k;
int a[n][n],s[n][n];
int dp[2*n][n][n][n][n];
int main ()
for(int tk=2; tk<=k; tk++)
for(int i=n; i>=1; i--)
for(int j=n; j>=1; j--)
for(int p=i; p<=n; p++)
for(int q=j; q<=n; q++)
printf("%d\n",dp[k][1][1][n][n]);
return 0;
}
P1436 棋盤分割
題意 給出乙個8 8的棋盤,讓我們將其分割成n塊,每一塊的值為 塊中所有數的和 2 求出在最優的分割方式下的最小值 思路 這是乙個分割問題,但直接考慮分割有點難,所以我們逆向考慮,將其想為填補問題,也就是說,將n塊矩陣填補成乙個8 8的矩陣的最小答案 那麼我們需要以下幾步 1.初始化,我們先求出二維...
洛谷 P1436 棋盤分割
如圖 思路 這是乙個很明顯的二維dp題,每一次分割的可以衍生出2種情況 左 上 右 下 2個新矩形 所以最優解一定存在於兩種新情況中,繼續進行遞迴求解即可 dp 左上座標x 左上座標y 右下座標x 右下座標y 分割次數 順推 dp i j k l num 新的上 左 下 右 矩形dp 切割零次時剩餘...
洛谷P1436 棋盤分割 題解 二維區間DP
這道題目和 演算法藝術與資訊學競賽 的題目描述稍微有點區別 這裡是求平方和的最小值,書上是方差的最小值 不過解法都是一樣的,就是區間dp,我這裡使用記憶化搜尋實現。f r1 c1 r2 c2 m 表示以 r1,c1 為左上角的格仔,以 r2,c2 為右下角的格仔,並且分成 m 份的最小平方和。實現 ...