zoukankan      html  css  js  c++  java
  • Sleep Buddies (二进制状态压缩)

    Sleep Buddies

     算法:状态压缩, 把每一个集合都压缩成一个数字。

    使用方法:把每个状态都进行1<<(x-1)压缩,这样的话我们可以保证,每个二进制上代表的那个数字是1就代表存在这个属性。

    AC_Code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=1e5+10;
     5 #define rep(i,first,last) for(ll i=first;i<=last;i++)
     6 #define dep(i,first,last) for(ll i=first;i>=last;i--)
     7 ll n,m,q,x,y,cnt;
     8 double k;
     9 ll vis[maxn];
    10 ll flag[maxn];
    11 void init(){//预处理一下每个数字的二进制中有几个1代表有几个属性
    12     ll z;
    13     rep(i,0,1023){
    14         z=i;
    15         while(z){
    16             if(z&1)flag[i]++;
    17             z>>=1;
    18         }
    19     }
    20 }
    21 
    22 signed main()
    23 {
    24     scanf("%lld%lld",&n,&m);
    25     rep(i,1,n){
    26         scanf("%lld",&q);
    27         y=0;
    28         rep(j,1,q){
    29             scanf("%lld",&x);
    30             y += (1<<(x-1));//每次输入q次x都要进行状态的压缩
    31         }
    32         vis[y]++;//对该集合压缩后用book记录与该集合相同的集合一共有几个,类似于桶排
    33     }
    34     scanf("%lf",&k);
    35     init();
    36     rep(i,1,1023){
    37         rep(j,i,1023){
    38             //如果其中有一个集合不存在那么就continue
    39             if( !vis[i]||!vis[j] )continue;
    40             ll f1=i&j;//二进制与运算,得到结果为两个集合相交后的结果
    41             ll f2=i|j;//并集的结果
    42             double ff=1.0*flag[f1]/flag[f2];
    43             if( ff<k ) continue;
    44             else{
    45                 if( i==j ) cnt+=vis[i]*(vis[j]-1)>>1;//这里用了一个等差数列前n项和 n*(n-1)/2
    46                 else cnt+=vis[i]*vis[j];
    47             }
    48         }
    49     }
    50     printf("%lld
    ",cnt);
    51     return 0;
    52 }
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=1e5+10;
     5 #define lowbit(x) x&(-x)
     6 #define rep(i,first,last) for(ll i=first;i<=last;i++)
     7 #define dep(i,first,last) for(ll i=first;i>=last;i--)
     8 ll n,m,q,x,y,cnt;
     9 double k;
    10 ll vis[maxn];
    11 ll flag[maxn];
    12 void init(){//预处理一下每个数字的二进制中有几个1代表有几个属性
    13     ll z;
    14     rep(i,0,1023){
    15         z=i;
    16         while(z){
    17             flag[i]++;
    18             z-=lowbit(z);
    19         }
    20     }
    21 }
    22 
    23 signed main()
    24 {
    25     scanf("%lld%lld",&n,&m);
    26     rep(i,1,n){
    27         scanf("%lld",&q);
    28         y=0;
    29         rep(j,1,q){
    30             scanf("%lld",&x);
    31             y += (1<<(x-1));//每次输入q次x都要进行状态的压缩
    32         }
    33         vis[y]++;//对该集合压缩后用book记录与该集合相同的集合一共有几个,类似于桶排
    34     }
    35     scanf("%lf",&k);
    36     init();
    37     rep(i,1,1023){
    38         rep(j,i,1023){
    39             //如果其中有一个集合不存在那么就continue
    40             if( !vis[i]||!vis[j] )continue;
    41             ll f1=i&j;//二进制与运算,得到结果为两个集合相交后的结果
    42             ll f2=i|j;//并集的结果
    43             double ff=1.0*flag[f1]/flag[f2];
    44             if( ff<k ) continue;
    45             else{
    46                 if( i==j ) cnt+=vis[i]*(vis[j]-1)>>1;//这里用了一个等差数列前n项和 n*(n-1)/2
    47                 else cnt+=vis[i]*vis[j];
    48             }
    49         }
    50     }
    51     printf("%lld
    ",cnt);
    52     return 0;
    53 }

    参考博客:点这里

  • 相关阅读:
    POJ 1811 Prime Test 素性测试 分解素因子
    sysbench的安装与使用
    电脑中已有VS2005和VS2010安装.NET3.5失败的解决方案
    I.MX6 show battery states in commandLine
    RPi 2B Raspbian system install
    I.MX6 bq27441 driver porting
    I.MX6 隐藏电池图标
    I.MX6 Power off register hacking
    I.MX6 Goodix GT9xx touchscreen driver porting
    busybox filesystem httpd php-5.5.31 sqlite3 webserver
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12367669.html
Copyright © 2011-2022 走看看