poj3254 pressure DP

Posted by Jaguar on Thu, 02 Jan 2020 04:05:30 +0100

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;
}