其他分享
首页 > 其他分享> > Acwing 291. 蒙德里安的梦想

Acwing 291. 蒙德里安的梦想

作者:互联网

题目大意

求把 N×M 的棋盘分割成若干个 1×2 的的长方形,有多少种方案。

1≤N,M≤11

思路:

一:

用f[i][s]表示第i行状态为s的方案数;
对于s 0表示i-1列无伸向第i列的方格,1表示有伸向第i列的方格;
先预处理可用状态(对这一题所有状态都可用)

点击查看代码
        state.clear();
        for(int i=0;i< 1<<n;i++)
        {
            state.push_back(i);
        }

二:

找可转移的状态 即 对于状态 a ,b 满足(a&b)==0&&check(a|b)

点击查看代码
		
	
	    bool check(int state)
		{
   		 int res=0;
    	bool flag=true;
   		 for(int i=0;i<n;i++)
    	{
        	if(state>>i &1)
        	{
            	if(res&1){
                	flag=false;
                	break;
            	}
            	res=0;
        	}
        	else res++;
    	}
   		 if(res&1) flag=false;
   		 return flag;
		}
	
		//main()里
        for(int i=0;i<state.size();i++)
        {
            head[i].clear();
            for(int j=0;j<state.size();j++)
            {
                int a=state[i],b=state[j];
                if((a&b) ==0&& check(a|b) )
                head[i].push_back(j);
            }
        }

三:

状态计算:

点击查看代码
        memset(f,0,sizeof(f ));
        f[0][0]=1;
        for(int i=1;i<=m;i++)
        {
            for(int a=0;a<state.size();a++)
            {
                for(int b:head[a])
                {
                    f[i][a]+=f[i-1][b];
                }
            }
        }
        cout<<f[m][0]<<endl;

全部代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=13;
const int M=1<<11;

vector<int> state;
vector<int> head[M];
long long f[N][M];
int n,m;
bool check(int state)
{
    int res=0;
    bool flag=true;
    for(int i=0;i<n;i++)
    {
        if(state>>i &1)
        {
            if(res&1){
                flag=false;
                break;
            }
            res=0;
        }
        else res++;
    }
    if(res&1) flag=false;
    return flag;
}
int main()
{
    while(cin>>n>>m,n||m)
    {
        state.clear();
        for(int i=0;i< 1<<n;i++)
        {
            state.push_back(i);
        }
        for(int i=0;i<state.size();i++)
        {
            head[i].clear();
            for(int j=0;j<state.size();j++)
            {
                int a=state[i],b=state[j];
                if((a&b) ==0&& check(a|b) )
                head[i].push_back(j);
            }
        }
        memset(f,0,sizeof(f ));
        f[0][0]=1;
        for(int i=1;i<=m;i++)
        {
            for(int a=0;a<state.size();a++)
            {
                for(int b:head[a])
                {
                    f[i][a]+=f[i-1][b];
                }
            }
        }
        cout<<f[m][0]<<endl;
    }
    
    return 0;
}

标签:false,蒙德里安,int,res,state,flag,bool,291,Acwing
来源: https://www.cnblogs.com/curlydog/p/15863982.html