#include<iostream>
using namespace std;
const int N=1<<6;
const int M=110;
const int T=30;
const int mod=1e9+7;
typedef long long ll;
ll f[M][N][N][T];//f[i][a][b][t] i 代表前i列 a代表前前列,b代表前面一列的状态集合 t代表已经用过多少个棋子
int lowit(int x){//计算当前列增加了多少个棋子
int res=0;
for(;x;x-=(x&-x))res++;
return res;
}
int main(){
int n,m,k;
cin>>n>>m>>k;
int maxn=1<<n;
f[0][0][0][0]=1;//初始化
for(int i=1;i<=m;i++)
for(int a=0;a<maxn;a++)
for(int b=0;b<maxn;b++)
if((a>>2)&b||a&(b>>2))continue;//判断前前列和前列有没有发生冲突剪枝
else
for(int c=0;c<maxn;c++){
if((c>>2)&b||c&(b>>2))continue;//判断前列和当前列有没有发生冲突
if((c>>1)&a||c&(a>>1))continue;//判断前前列和当前列有没有发生冲突
int t=lowit(c);
for(int tt=t;tt<=k;tt++)//背包计算个数
f[i][b][c][tt]=(f[i][b][c][tt]+f[i-1][a][b][tt-t])%mod;
}
int res=0;
for(int i=0;i<maxn;i++)//对前前列和前列不同的状态最终有多少个可以摆放的方案数
for(int j=0;j<maxn;j++)
res=(res+f[m][i][j][k])%mod;
cout<<res;
}
作者:沙烬
链接:https://www.acwing.com/solution/content/43484/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
acwing 3494 国际象棋 状态压缩dp (qwq)2022/03/06
于 2022-03-06 22:14:32 首次发布