Given a matrix of n * m, there are numbers 0 and on the matrix, which indicate that the coordinates can be placed. The objects to be placed cannot be adjacent. How many put methods are there? N, m <= 12
Solution: In simple state DP, dp [I] [j] indicates the number of methods in which things are placed on line I. j is the sum of several binary numbers, indicates which columns are placed with things.
Then perform recursion, dp [I] [j] = sum (dp [I-1] [k]) (k State and j State do not conflict)
Test data:
2 3
1 1 1
0 1 0
Code:
[Cpp]
# Include <stdio. h>
# Include <string. h>
# Define MIN 15
# Define MAX (1 <13)
# Define MOD 100000000.
Int dp [MIN] [MAX], n, m;
Int ans, map [MIN] [MIN], state [MIN];
Int CheckAdj (int st ){
Return! (St & (st> 1 ));
}
Int CheckPre (int cur, int pre ){
Return! (Cur & pre );
}
Void State_Dp (){
Int I, j, k, st = (1 <m );
// Initialization
For (I = 0; I <st; ++ I)
If (I = (I & state [0]) & CheckAdj (I ))
Dp [0] [I] = 1; // printf ("0% d % d \ n", I, dp [0] [I]);
// Status transfer dp [I] [j] = sum (dp [I-1] [k]) (! (J & k) that is, the status j does not conflict with the status k)
For (I = 1; I <n; ++ I)
For (j = 0; j <st; ++ j)
If (j = (j & state [I]) & CheckAdj (j )){
Int sum = 0;
For (k = 0; k <st; ++ k)
If (CheckPre (j, k) sum = (sum + dp [I-1] [k]) % MOD;
Dp [I] [j] = sum; // printf ("I = % d j = % d \ n", I, j, dp [I] [j]);
}
}
Int main ()
{
Int I, j, k;
Scanf ("% d", & n, & m );
For (I = 0; I <n; ++ I)
For (j = 0; j <m; ++ j ){
Scanf ("% d", & map [I] [j]);
If (map [I] [j] = 1)
State [I] | = (1 <j );
}
State_Dp ();
For (ans = I = 0; I <(1 <m); ++ I)
Ans = (ans + dp [n-1] [I]) % MOD;
Printf ("% d \ n", ans );
}
Author: woshi250hua