JZOJ 3632. 【汕头市选2014】舞伴
2017-03-03 20:05
183 查看
Description
N 个男孩,N 个女孩,男孩和女孩可能是朋友,也可能不是朋友。现在要组成N 对舞伴,要求每对舞伴都是一男一女,且他们是朋友。
统计不同配对方案的数量,因为结果很大,所以只要求除以M 的余数。
Input
第1 行,2 个整数N,M。接下来N 行,每行N 个整数Aij,表示第i 个男孩和第j 个女孩的关系。如果他们是朋友,则Aij = 1,否则Aij = 0。Output
1 个整数,表示所求的值。Sample Input
3 10000000001 1 1
1 1 1
1 1 1
Sample Output
6Data Constraint
• 对于50% 的数据,N <= 9;• 对于100% 的数据,1 <= N <= 20, 1 <= M <= 10^9; 0 <= Aij <= 1。
Solution
这题一看 N≤20 就知道是状压DP啦!设 f[i][s] 表示选了前 i 个男孩,已选女孩状态为 s 的方案数。
显然可得:f[i][s]+=f[i−1][s′]
每个男孩向是朋友的女孩转移即可,还可以开滚动节约空间。
总时间复杂度为 O(2N∗N2) 。
Code
#include<cstdio> #include<cstring> using namespace std; int roll; int a[21],p[21]; int f[2][1<<20]; inline int read() { int data=0; char ch=0; while(ch<'0' || ch>'9') ch=getchar(); while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar(); return data; } int main() { int n=read(),m=read(); for(int i=p[0]=1;i<=n;i++) p[i]=p[i-1]*2; for(int i=f[0][0]=1;i<=n;i++) { roll=1^roll; memset(f[roll],a[0]=0,sizeof(f[roll])); for(int j=1;j<=n;j++) if(read()) a[++a[0]]=j; for(int s=0;s<p ;s++) if(f[1^roll][s]) for(int j=1;j<=a[0];j++) if(!(s&(p[a[j]-1]))) f[roll][s|p[a[j]-1]]=(f[roll][s|p[a[j]-1]]+f[1^roll][s])%m; } printf("%d",f[roll][p -1]); return 0; }
相关文章推荐
- 【汕头市选2014】舞伴 jzoj 3632 状压dp
- 【jzoj3632】【汕头市选2014】【舞伴】【状态压缩动态规划】
- JZOJ3632【汕头市选2014】舞伴(perm)
- 【汕头市选2014】舞伴(perm)
- 【JZOJ3633】【汕头市选2014】数数(count) (栈)
- JZOJ3630. 【汕头市选2014】分叉(fork)
- 【汕头市选2014】舞伴(perm)
- jzoj3630 【汕头市选2014】分叉(树上统计)
- jzoj P1842【汕头市选2014】平均
- jzoj 3631 【汕头市选2014】三角(triangle)
- jzoj P1843【汕头市选2014】小球
- jzoj P1845【汕头市选2014】约数
- 【汕头市选2014】舞伴(perm)
- JZOJ 1842——【汕头市选2014】平均
- 汕头市选 2014 舞伴___状压dp
- 【汕头市选2014】分叉 jzoj 3630 dfs
- 【jzoj3630】【汕头市选2014】【分叉】【树形动态规划】
- JZOJ 3631. 【汕头市选2014】三角(triangle)
- JZOJ 3806. 【NOIP2014模拟8.24】小X 的道路修建
- JZOJ 3809. 【NOIP2014模拟8.25】设备塔