棋盘问题
题目描述
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
题解
状压dp dp[i][j]表示第I行此时状态为j的方案数.j表示列的状态
代码
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int cnt,ans,n,k,dp[11][1<<8]; char mp[9][9]; int main(){ while(scanf("%d%d",&n,&k)!=EOF){ ans=0; memset(dp,0,sizeof(dp)); if(n==-1&&k==-1)break; for(int i=1;i<=n;i++) scanf("%s",mp[i]); dp[0][0]=1; for(int i=1;i<=n;i++){ for(int j=0;j<(1<<n);j++){ for(int p=0;p<n;p++){ if(mp[i][p]=='#'&&(j&(1<<p))==0) dp[i][j|(1<<p)]+=dp[i-1][j]; } dp[i][j]+=dp[i-1][j]; } } for(int j=0;j<(1<<n);j++){ cnt=0;int i=j; for(;i;i-=i&-i)cnt++;//i&(-i)一直找最后一个1 if(cnt==k)ans+=dp[n][j]; } printf("%d ",ans); } return 0; }