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;
}

  

posted @ 2020-01-06 16:42  EM-LGH  阅读(166)  评论(0编辑  收藏  举报