POJ 1191 棋盤分割

2021-06-27 05:39:51 字數 1684 閱讀 2114

題意:給定一8*8的棋盤,每次沿著邊將棋盤切成兩部份,把一部分放到一邊,再繼續切另一部分,切n-1次得到n個矩形塊,問使n個塊的和能達到的最小方差。

題解:顯然可以每次遍歷對矩形塊的橫切和豎切,當dfs到份數等於1,利用二維線段樹組將矩形塊的和求出來返回即可。

剪枝:當訪問到同個矩形塊,相同切割份數時,利用儲存的值直接返回即可。

乙個n*m的矩形塊,易知如果n,m不等,最多份數的切割必定是先把矩形一步步切成正方形,然後對正方形邊緣一步步切割得到1*1的矩形塊,假設n,m為8*7,則最大份數的切割方案為:8*7->7*7->7*6->6*6->...->2*1->1*1,歸納的n*m的矩形塊最多可劃分n+m-1份。

#include#include#include#includeusing namespace std;

#define square(x) ((x)*(x))

class solve

int processin();

int low_bit(int x);

int addsum(int x,int y,int val);

int sumbranch(int x,int y);

int calcsum(int left_x,int left_y,int right_x,int right_y);

int dfs(int left_x,int left_y,int right_x,int right_y,int n);

};int solve::dfs(int left_x,int left_y,int right_x,int right_y,int n)

int i;

int val1,val2;

for(i = left_x+1;i < right_x;i++) //遍歷可能的所有的縱切

val1 = dfs(left_x,left_y,i,right_y,1);

val2 = dfs(i,left_y,right_x,right_y,n-1);

if(val1 != -1&&val2 != -1)

}for(i = left_y+1;i < right_y;i++) //遍歷可能的所有橫切

val1 = dfs(left_x,left_y,right_x,i,1);

val2 = dfs(left_x,i,right_x,right_y,n-1);

if(val1 != -1&&val2 != -1)

}minsquare[left_x][left_y][right_x][right_y][n] = tmpval;

return tmpval == 1e8?-1:tmpval;

}int solve::sumbranch(int x,int y)

}return tmpsum;

}int solve::calcsum(int left_x,int left_y,int right_x,int right_y)

int solve::low_bit(int x)

int solve::addsum(int x,int y,int val)

}return 0;

}int solve::processin()

}meanval /= n;

return 0;

}int main()

return 0;

}

poj 1191 棋盤分割

棋盤分割 time limit 1000ms memory limit 10000k total submissions 10807 accepted 3798 description 將乙個 的棋盤進行如下分割 將原棋盤割下一塊矩形棋盤並使剩下部分也是矩形,再將剩下的部分繼續如此分割,這樣割了 n...

POJ 1191 棋盤分割

題目點我 經典的動態規劃題目,首先將標準差公式變形一下 ni 1 xi x 2n n 2 x 2 i 1nx 2i由於x 是固定的,與分割方案無關,所以求最小的標準差就相當於求最小的平方和的分割方案。定義狀態需要五個維度 描述乙個矩形需要四個維度 左上角座標x1 y1 和右下角座標x2 y2 要分割...

棋盤分割 POJ 1191

1 題目型別 dp 概率論。2 解題思路 dp遞推式 以上下切為例 for i x1.x2 sum k x1 y1 x2 y2 min 其中 i 表示切割位置,k 表示切割次數。3 注意事項 遞迴迴圈的呼叫。4 參考部落格 5 實現方法 include iostream include cmath ...