tdpc S - マス目
有一个 \(h\times w\) 的矩形,给矩形黑白染色,问有多少种染色方法符合
- \((0,0)\),\((h-1,w-1)\) 是黑色
- 从点 \((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
*/

浙公网安备 33010602011771号