Description
【问题描述】
Wcyz为了迎接百年校庆,美化校园,请了校友笨笨将n座雕塑,准备安置在校园内,整个校园可以抽象成一个nn的大网格,每个11网格最多只能安置一座雕塑,但是某些1*1的网格上恰好是一个食堂或湖泊,这些网格是不能安置雕塑的,每个雕塑的造型相同,这样同一种安置方案中交换排列都算一种。任意雕塑在同一行或同一列是不合法的方案。
学校想知道有多少种安置方案,笨笨想从中选择最好的一种方案,笨笨想请你告诉他方
案种数。
Input
【输入格式】
第一行,两个整数n,m(n<=20,m<=10),用空格隔开,n表示n*n的大网格,m表示不能安置雕塑的位置
第二行至m+1行,每行两个数x,y,用空格分开,表示坐标(x,y)的1*1 的网格上不能安置雕塑。
Output
【输出格式】
一个数,方案种数(方案种数<=2^63-1)
Sample Input
6 7
1 1
2 1
2 2
3 3
3 4
4 3
4 4
Sample Output
184
Data Constraint
Hint
n<=20,m<=10
状态压缩板子题
f[i]代表已经选了格子一共有多少种方案,(选了的列用1来表示)。tr是判断是否不能放的
#include<bits/stdc++.h>
using namespace std;
long long tr[101],x,y,f[1<<21],ts;
long long find (int i)
{
int t=0;
while (i)
{
if (i&-i) t++;
i-=i&-i;
}
return t;
}
int main()
{
int n,m;
cin>>n>>m;
f[0]=1;
for (int i=1;i<=n;i++)
tr[i]=(1<<n)-1;
for (int i=1;i<=m;i++)
cin>>x>>y,tr[x]-=1<<(y-1);
for (int i=1;i<=(1<<n)-1;i++)
{
int c=find(i);
ts=i&tr[c];
for (int j=ts;j>0;j-=j&-j)
f[i]+=f[i^(j&-j)];
}
cout<<f[(1<<n)-1];
}