Title Link
Ideas from Big guy blog
The state can be represented by binary system. Just convert each state to corresponding decimal number, and only one number can represent a certain state
dp[i][state(j)] is used to express the total number of feasible schemes that can be obtained when the first I line is in the j state!
For example: looking back at the sample data, dp[2][1] represents the number of schemes available when the second row uses the second state (0.10), that is, 4;
Then, the equation of state transition can be obtained as follows:
dp[i][state(j)]=dp[i-1][state(k1)]+dp[i-1][state(k2)]+…… +dp[i-1][state(kn)](kn is the number of feasible states i n the previous line, and there are n feasible states in the previous line)
Finally, ans=dp[m][state(k1)]+dp[m][state(k2)] + +dp[m][state(kn)]; (kn is the number of feasible state in the last row (row m))
//Pressure DP
#include<cstdio>
#include<cstring>
using namespace std;
#define mod (int)1e8
int M,N,top=0;
//top indicates the maximum number of states per row
int state[600],num[110];
//state stores all available states in each line
int dp[20][600];
//dp[i][j]: for the first I rows of data, the solution when each row has the first j possible states
int cur[20];
//cur[i] indicates the whole line of line I
inline bool ok(int x)//Judge whether state x is feasible
{
if(x&x<<1)return false;//If two adjacent lattices are all 1, then this state is not feasible
return true;
}
void init()//Traverse all possible states
{
top=0;
int total=1<<N;//The upper bound of ergodic state
for(int i=0;i<total;i++)
if(ok(i))state[++top]=i;
}
inline bool fit(int x,int k)//Judge whether the inverse of state x and the actual state of line k coincide
{
if(x&cur[k])return false;//If there is overlap, x does not meet the requirements
return true;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&M,&N)!=EOF)
{
init();//Traverse all possible states
memset(dp,0,sizeof(dp));//Initialization
for(int i=1;i<=M;i++)
{
cur[i]=0;
int num;
for(int j=1;j<=N;j++)//When inputting, it is stored bit by bit. cur[i] represents the whole line of line I, and the binary of the number represents one bit every time it is changed
{
scanf("%d",&num);//Indicates row i, column j (0 or 1)
if(num==0)//If the lattice is 0
cur[i]+=(1<<(N-j));//Then the location is 1 (stored in the opposite way, 1 means no grazing)
}
}
for(int i=1;i<=top;i++)
if(fit(state[i],1))//Determine whether the inverse of all possible states coincides with the actual state of the first line
dp[1][i]=1;
//In the process of state transition, dp[i][k] = ∑ dp[i-1][j](j is all states that meet the conditions)
for(int i=2;i<=M;i++)//i index lines 2 through M
for(int k=1;k<=top;k++)//The loop finds a set of state[k] that matches line i of line i for all possible states
{
if(!fit(state[k],i))continue;//Judge whether it is in line i
for(int j=1;j<=top;j++)//After finding the state[k], find a set of state state[j] that conforms to line i-1 and does not conflict with line I (state[i])
{
if(!fit(state[j],i-1))continue;//Judge whether it is in line i-1
if(state[k]&state[j])continue;//Judge whether it conflicts with line i
dp[i][k]=(dp[i][k]+dp[i-1][j])%mod;//If all of the above can be passed, then add j to k
}
}
int ans=0;
for(int i=1;i<=top;i++)//Accumulate the values of all possible states in the last row
ans=(ans+dp[M][i])%mod;
printf("%d\n",ans);
}
return 0;
}