[Jzoj] 3059.雕塑
作者:互联网
题目大意
校友笨笨将N座雕塑,准备安置在校园内,整个校园可以抽象成一个N∗N的大网格,每个1∗1网格最多只能安置一座雕塑,但是某些1∗1的网格上不能安置雕塑的,每个雕塑的造型相同,这样同一种安置方案中交换排列都算一种。任意雕塑在同一行或同一列是不合法的方案。求方案数。
题目解析
很明显的是一个状压DP。
先设F[i]表示当前状态为i的方案数,先处理出ar表示第r行不允许放置的情况。
因为题意说明了一行只能放置一个,所以当前状态当前枚举的状态i中1的个数,就可以判断出是放到第几行。
对于需要处理的状态i,用t=i&~a[r](r表示当前行)来代替i进行枚举,既不枚举i中的1转移而是枚举t中的1。
因为t保证了不允许放置的位为0,这样就可以不用其它的判断来实现算法。
代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
long long a[25],f[1<<21];
int main()
{
cin>>n>>m;
for(int i=1,x,y;i<=m;i++)
{
cin>>x>>y;
a[x]|=(1<<(y-1));
}
f[0]=1;
int t,c;
for(int i=1;i<1<<n;i++)
{
for(t=i,c=0;t;c++,t-=t&-t);
t=i&~a[c];
while(t)
{
f[i]+=f[i^(t&-t)];
t-=t&-t;
}
}
cout<<f[(1<<n)-1];
}
标签:11,Jzoj,安置,雕塑,网格,枚举,3059,iii 来源: https://blog.csdn.net/weixin_43909855/article/details/95655468