• 【BZOJ2560】串珠子(状压DP,容斥原理)


    题意:

    铭铭有n个十分漂亮的珠子和若干根颜色不同的绳子。现在铭铭想用绳子把所有的珠子连接成一个整体。
    现在已知所有珠子互不相同,用整数1到n编号。对于第i个珠子和第j个珠子,可以选择不用绳子连接,或者在c[i,j]根不同颜色的绳子中选择一根将它们连接。

    如果把珠子看作点,把绳子看作边,将所有珠子连成一个整体即为所有点构成一个连通图。特别地,珠子不能和自己连接。
    铭铭希望知道总共有多少种不同的方案将所有珠子连成一个整体。由于答案可能很大,因此只需输出答案对1000000007取模的结果。

    n<=16,a[i][j]<=1e9+7

    思路:

    还记得n个点有标号的无向连通图个数怎么求吗?如果记得的话,此题就简单了。
    用f[S]表示与1号点连通的点的状态为S的方案数。我们先与处理出g数组,g[S]=∏u,v∈S(c[u][v]+1),然后f[S]就等于g[S]减去S中某些点与1号点不连通的方案数。
    那么我们枚举此时与1号点连通的点的状态,其余的点与这个连通块均没有边相连,但是其余的点之间可以任意连边,
    所以有:
    f[S]=∑S′⊊Sf[S′]×g[S−S′]
    所以时间复杂度就是枚举子集的O(3^n)
    需要注意的是k=log(x)/log(2)+1这种写法似乎在BZOJ上不能用,需要预处理或者暴力
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstring>
     6 #include<map>
     7 #include<set>
     8 #include<cmath>
     9 using namespace std;
    10 long long dp[1<<17],f[1<<17];
    11 long long a[17][17];
    12 const int MOD=1000000007;
    13 int n;
    14    
    15 int lowbit(int x)
    16 {
    17     return (x&(-x));
    18 }
    19  
    20 int who(int x)
    21 {
    22     int s=0;
    23     int k=x;
    24     while(k)
    25     {
    26         s++;
    27         k>>=1;
    28     }
    29     return s;
    30 }
    31  
    32 int main()
    33 {
    34    
    35     scanf("%d",&n);
    36     for(int i=1;i<=n;i++)
    37      for(int j=1;j<=n;j++) scanf("%lld",&a[i][j]);
    38     f[0]=1;
    39      
    40     int M=(1<<n)-1;
    41     for(int i=1;i<=M;i++)
    42     {
    43         int x=lowbit(i);
    44         int y=who(x);
    45         f[i]=f[i-x];
    46         for(int j=1;j<=n;j++)
    47          if((y!=j)&&(i&(1<<(j-1)))) f[i]=f[i]*(a[y][j]+1)%MOD;
    48     }
    49     
    50     dp[1]=1;
    51     for(int i=2;i<=M;i++)
    52      if(i&1)
    53      {
    54         int v=(i-1);
    55         dp[i]=f[i];
    56         while(v)
    57         {
    58             dp[i]=dp[i]-(f[v]*dp[i-v])%MOD;
    59             dp[i]=(dp[i]%MOD+MOD)%MOD; 
    60             v=((i-1)&(v-1)); 
    61         }
    62      }
    63     printf("%lld
    ",dp[M]);
    64     return 0;
    65 }
  • 相关阅读:
    小程序苹果手机上video会盖住绝对定位的view层,小程序 video 层级,原生组件
    两个高斯分布乘积的理论推导
    两个高斯分布的和的分布——正态分布的再生性
    随机变量、随机向量和随机有限集的定义
    UdpClient.BeginReceive(AsyncCallback, Object) 方法
    基于C#的UDP协议的异步实现
    基于C#实现串口通信Demo
    pitch、yaw、roll三个角的区别
    dotNET Core 3.X 使用 Jwt 实现接口认证
    C#使用RabbitMQ
  • 原文地址:https://www.cnblogs.com/myx12345/p/9302101.html
Copyright © 2020-2023  润新知