3059. 雕塑

校园为迎接校庆要在n*n网格安置n座雕塑,部分网格不能安置,且雕塑不能在同一行或列。需计算安置方案种数,这是状态压缩板子题,用f[i]表示选了格子的方案数,tr用于判断能否放置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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];  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值