BZOJ 2560: 串珠子 状压DP+容斥原理
这个题和那个城市规划几乎是一个套路.
就是钦定一个点,然后枚举这个点所在连通块大小,然后其余部分随便连.
由于我们钦定了一个点,所以我们算的方案数肯定不会重复.
即 $f[S]=TOT(S)-\sum_{T \subseteq S} f(T) \times TOT(S-T)$.
code:
#include <cstdio> #include <algorithm> #define ll long long #define mod 1000000007 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n; ll g[67000],f[67000],c[20][20]; void pre(int S) { g[S]=1; for(int i=1;i<=n;++i) { if((1<<(i-1))&S) for(int j=i+1;j<=n;++j) if((1<<(j-1))&S) (g[S]*=(c[i][j]+1))%=mod; } } int main() { // setIO("input"); int i,j; scanf("%d",&n); for(i=1;i<=n;++i) for(j=1;j<=n;++j) scanf("%lld",&c[i][j]); for(i=0;i<(1<<n);++i) pre(i); for(int S=0;S<(1<<n);++S) { f[S]=g[S]; int i=S^(S&-S); for(int j=i;j;j=(j-1)&i) f[S]=(f[S]-g[j]*f[S^j]%mod+mod)%mod; } printf("%lld\n",f[(1<<n)-1]%mod); return 0; }