description
在乙個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案c。
input
輸入含有多組測試資料。
每組資料的第一行是兩個正整數,n k,用乙個空格隔開,表示了將在乙個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n
當為-1 -1時表示輸入結束。
隨後的n行描述了棋盤的形狀:每行有n個字元,其中 # 表示棋盤區域, . 表示空白區域(資料保證不出現多餘的空白行或者空白列)。
output
對於每一組資料,給出一行輸出,輸出擺放的方案數目c (資料保證c<2^31)。
題意:
在棋盤上任意擺放k個棋子,注意棋子不能上下左右相鄰,本題中棋盤能放棋子的區域只有「#」所代表的區域,「.」代表的區域不能放棋子。
題解:
本題可以使用狀態壓縮dp,狀態壓縮也就是用二進位制表示狀態,本題中用0表示「.」,用1表示「#」,例如:
…#:0001
.#.#:0101
因為n<=8,所以我們至多用2的8次方即256就可以表示每一行的所有可能狀態。
(1)我們用dp[i][j]表示從第1行到第i行在第i行為j狀態下能夠表示的種類數量。
(2)針對每一行的狀態j,因為棋子左右不能相鄰,所以需要滿足j&(j-1)==0。
(3)對於相鄰的兩行狀態j、k,要滿足j&k==0.
(4)如果滿足上面的條件,那麼dp[i][j] = sum(dp[i-1][k])
通過上面的條件進行動態規劃可以得到結果。
#include
#include
#include
#define maxn 300
using
namespace
std;
char c[10][10];
int dp[10][maxn];
int num[maxn];
int n,k,sum;
long
long ans;
void cal()}}
}}
ans = 0;
for(int i = 0; i < (1
<< n); i++)
cout
<< ans << endl;
}return
0;}
POJ 1321 棋盤問題
time limit 1000ms memory limit 10000k total submissions 7007 accepted 3390 description 在乙個給定形狀的棋盤 形狀可能是不規則的 上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列...
poj 1321 棋盤問題
棋盤問題 time limit 1000ms memory limit 10000k total submissions 15365 accepted 7600 description 在乙個給定形狀的棋盤 形狀可能是不規則的 上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一...
POJ 1321 棋盤問題
找到第乙個有 的行開始回溯就可以了 include include using namespace std const int maxn 9 char board maxn maxn bool c maxn int ans,n,k void backtracking int curi,int cnt...