tdpc S - マス目

有一个 \(h\times w\) 的矩形,给矩形黑白染色,问有多少种染色方法符合

  1. \((0,0)\)\((h-1,w-1)\) 是黑色
  2. 从点 \((0,0)\) 开始只走黑点,能走的方向为上下左右,可以到达 \((h-1,w-1)\) .

\(10^9+7\).

\(1\leq h\leq 6\)\(1\leq w\leq 100\)

观察发现,可能存在蛇形行走的情况,而且 \(h\) 的范围非常小,可以考虑维护行的情况.

需要一个 \(dp(i,state)\)\(dp\) 进行转移.

可以维护行的联通情况,并且,有一个连通块必定和格子 \((0,0)\) 相连,需要特殊标记.

接着,枚举新一行的染色情况,可以得到新的联通情况, 其中必须满足与格子 \((0,0)\) 相连.

我用 map <pair<int,vector<int> > > 存储. 所以 vector<int> 必须有序.

然后我的代码跑了 200 ms+ .

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int n,m;
map<pair<int,vector<int> >,int>dp[2];
int fa[6];
bool col[6];
inline void upd(int &x,int y){x+=y;x%=mod;}
inline int get_fa(int x){return fa[x]==x?x:fa[x]=get_fa(fa[x]);}
inline void unite(int x,int y){
	x=get_fa(x);y=get_fa(y);
	if(x==y)return;
	fa[x]=y;
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(int mask=0;mask<(1<<n);mask++){
		if(!(mask&1))continue;
		for(int i=0;i<n;i++)fa[i]=i;
		for(int i=0;i<n;i++){
			if(mask&(1<<i))col[i]=true;
			else col[i]=false;
		}
		for(int i=1;i<n;i++)if(col[i]&&col[i-1])unite(i,i-1);
		vector<int>v;
		for(int i=0;i<n;i++){
			int tmp=0;
			for(int j=0;j<n;j++)if(get_fa(j)==i)tmp|=1<<j;
			if(tmp==0)continue;
			v.push_back(tmp);
		}
		sort(v.begin(),v.end());
		int id=-1;
		for(int i=0;i<(int)v.size();i++)if(v[i]&1)id=i;
		upd(dp[0][make_pair(id,v)],1);
	}
	for(int colu=0;colu+1<m;colu++){
		int cur=colu&1,nxt=cur^1;
		dp[nxt].clear();
		for(map<pair<int,vector<int> >,int>::iterator it=dp[cur].begin();it!=dp[cur].end();it++){
			vector<int>v=it->first.second;
			int id=it->first.first;
			for(int mask=0;mask<(1<<n);mask++){
				for(int i=0;i<n;i++){
					if(mask&(1<<i))col[i]=true;
					else col[i]=false;
				}
				bool flag=false;
				int sts=v[id];
				for(int i=0;i<n;i++)if(sts&(1<<i))if(col[i])flag=true;
				if(!flag)continue;
				for(int i=0;i<n;i++)fa[i]=i;
				for(int i=1;i<n;i++)if(col[i]&&col[i-1])unite(i,i-1);
				int nsts=0;
				for(int i=0;i<v.size();i++){
					int s=v[i];
					for(int j=0;j<n;j++)if(s&(1<<j)){
						if(!col[j])continue;
						for(int k=0;k<n;k++)if(s&(1<<k)){
							if(!col[k])continue;
							unite(j,k);
						}
					}
					if(i==id){
						for(int j=0;j<n;j++){
							if(sts&(1<<j)){
								if(!col[j])continue;
								nsts|=1<<j;
							}
						}
					}
				}
				vector<int>nv;
				for(int i=0;i<n;i++){
					int s=0;
					for(int j=0;j<n;j++)if(get_fa(j)==i)s|=1<<j;
					if(s==0)continue;
					nv.push_back(s);
				}
				sort(nv.begin(),nv.end());
				int nid=-1;
				for(int i=0;i<(int)nv.size();i++)if((nsts&nv[i])>0)nid=i;
				upd(dp[nxt][make_pair(nid,nv)],it->second);S
			}
		}
	}
	int id=(m-1)&1,ans=0;
	for(map<pair<int,vector<int> >,int>::iterator it=dp[id].begin();it!=dp[id].end();it++){
		int id=it->first.first;
		int mask=it->first.second[id];
		if(mask&(1<<(n-1)))upd(ans,it->second);
	}
	cout<<ans<<endl;
	return 0;
}
/*inline? ll or int? size? min max?*/
/*
2 2
*/
posted @ 2021-07-07 19:29  xyangh  阅读(65)  评论(0)    收藏  举报