【SSL】1382车(状压)
Time Limit:1000MS Memory Limit:65536K
Description
在n*n(n≤20)的方格棋盘上放置n个车(可以攻击所在行、列),有些格子不能放,求使它们不能互相攻击的方案总数。
Input
第一行为棋盘的大小n
第二行为障碍的数量m
第三行到第m+3为m个障碍
Output
总数
Sample Input
4
2
1 1
2 2
Sample Output
14
思路
用一个二进制数表示一行状态
f[i]=f[i-某一位1]+……+f[i-某一位1]
f[(1011)2]=f[(11)2]+f[(1001)2]+f[(1010)2]
代码
#include<iostream>
#include<cstdio>
using namespace std;
long long a[1048576],f[1048576];
long long js(long long x)
{
long long ans;
for(ans=0;x;x-=x&-x,ans++);
return ans;
}
int main()
{
ios::sync_with_stdio(false);
long long n,m,i,j,x,y,tem,nn;
cin>>n>>m,nn=(1<<n)-1;
for(i=0;i<=nn;i++)a[i]=nn;
for(i=0;i<m;i++)cin>>x>>y,a[x]-=1<<(y-1);
for(f[0]=1,i=1;i<=nn;i++)
for(j=tem=a[js(i)]&i;j;j-=j&-j)
f[i]+=f[i-(j&-j)];
cout<<f[nn];
return 0;
}