Description
在n*n(n≤20)的方格棋盘上放置n个车(可以攻击所在行、列),有些格子不能放,求使它们不能互相攻击的方案总数。
Input
第一行为棋盘的大小n
第二行为障碍的数量m
第三行到第m+3为m个障碍
Output
总数
Analysis
n≤20
所以位运算+搜索,记忆化可以搞一下
开错数组的惨痛教训不能忘,果断开大一倍
Code
#include <stdio.h>
using namespace std;
long long mr[2048576],b[41],lim,n,m;
__attribute__((optimize("O2")))
inline void dfs(int dep,long long now)
{
if (mr[now])
return;
long long p=now|b[dep];
while (p!=lim)
{
long long tmp=p;
p|=(p+1);
long long pos=p^tmp;
dfs(dep+1,now|pos);
mr[now]+=mr[now|pos];
}
}
__attribute__((optimize("O2")))
int main()
{
scanf("%lld%lld",&n,&m);
lim=(1<<n)-1;
for (int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
b[x]|=(1<<(y-1));
}
mr[lim]=1;
dfs(1,0);
printf("%lld\n",mr[0]);
return 0;
}