zoukankan      html  css  js  c++  java
  • P5933 [清华集训2012]串珠子

    Lisa

    显然状态压缩

    然后,对于一个点集S,我们很容易求出这个点集可以形成的任意图(F_S)

    这个很容易预处理出来

    然后呢,对于这个直接求联通的方案书并不容易,但是,可以用总方案减去不连通的方案数。

    不连通的方案视为两个点集,一个点集随便,另一个点集必须联通。

    所以在预处理完了以后,我们首先要做的就是在当前集合里剥出一个点作为强制的联通集合的点,然后枚举这个集合剥离后的子集作为随意点,其子集的补集作为联通点集。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define int long long
    using namespace std;
    int n;
    int ma[101][101];
    int maxn=18;
    int f[1<<18];
    int dp[1<<18];
    int g[1<<18];
    int m=1000000007;
    int cnt;
    signed main(){
    	scanf("%d",&n);
    	cnt=(1<<n)-1;
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			scanf("%d",&ma[i][j]);
    		}
    	}
    	for(int k=0;k<=cnt;++k){
    		f[k]=1;
    		for(int i=1;i<=n;++i){
    			if(k&1<<i-1){
    				for(int j=i+1;j<=n;++j){
    					if(k&1<<j-1){
    						f[k]=f[k]*(ma[i][j]+1)%m;
    						f[k]%=m;
    					}
    				}
    			}
    		}
    	}
    	for(int k=1;k<=cnt;++k){
    		dp[k]=f[k];
    		int frm=k^(k&-k);
    		for(int i=frm;i;i=(i-1)&frm){
    			dp[k]=(dp[k]-f[i]*dp[i^k]%m+m)%m;
    		}
    	}
    	cout<<dp[cnt];
    	return 0;
    }
    
  • 相关阅读:
    iOS 添加微信分享
    IOS学习笔记——ViewController生命周期详解
    UI之CALayer详解(转)
    iOS CALayer讲解
    [leetcode] Minimum Path Sum
    [leetcode]Binary Tree Maximum Path Sum
    我是真的想去google啊
    C++ string 用法详解
    继续存博客
    bash中 2>&1 & 的解释
  • 原文地址:https://www.cnblogs.com/For-Miku/p/15063359.html
Copyright © 2011-2022 走看看