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 }

    参考博客:点这里

  • 相关阅读:
    Single Page Application
    ES6数组方法
    localStorage 和 sessionStorage
    border-color:transparent;
    自适应屏幕高度铺满全屏
    href="#"与javascript:void(0)的区别
    图片模式CMYK和RGB在浏览器下的变化
    IE css HACK
    z-index只能用在定位元素上
    mysql锁机制之间隙锁(Next-Key锁)(五)
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12367669.html
Copyright © 2011-2022 走看看