关于二进制运算

如果要求字符串s的子集  s是只由A和B组成的,则可以把A看作1 B看作0 进而把s转换成一个由1和0组成的二进制数 S

则求S的子集就可以用以下代码来实现

int len = s.size()
for(int i=1; i< 1<<len; i++)
{
    num[cnt++] = S & i;
}

因为从0到1<<len-1 包含了由1和0组成的所有情况 又因为&的性质 所以可以实现求子集

例题:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=820&pid=1001

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 10010, INF = 0x7fffffff;
int num[maxn], temp[maxn], vis[maxn];
int n, m, k;

int main()
{
    int T, kase = 0;
    cin>> T;
    while(T--)
    {
        int ans = 0;
        mem(num, 0);
        mem(vis, 0);
        cin>> n >> m >> k;
        string str;
        rap(i, 1, n)
        {
            cin>> str;
            rap(j, 0, m-1)
            {
                if(j != 0)
                    num[i] <<= 1;
                if(str[j] == 'A')
                    num[i] ^= 1;
            }
          //  cout<< num[i] <<endl;
        }
        int res = 0;
        for(int i=1; i < 1<<m; i++)
        {
            mem(vis, 0);
            mem(temp, 0);
            int cnt = 0;
            res = 0;
            for(int j=1; j<=n; j++)
            {
                int t = num[j] & i;
                if(!vis[t]) temp[cnt++] = t;
                vis[t]++;
            }
            for(int j=0; j<cnt; j++)
            {
                for(int q=j+1; q<cnt; q++)
                {
                    res += vis[temp[j]] * vis[temp[q]];
                }
            }
            if(res >= k)
                ans++;
        //    cout<< res <<endl;
        }

        printf("Case #%d: %d
", ++kase, ans);
    }


    return 0;
}

当然二进制也可以用于全排列

例题

hdu 1074

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

public class Main{
    final static int maxn = 1<<16;
    final static int INF = 0xfffffff;
    public static int n;
    public static class node{
        String name = new String();
        int d,c;
        node(String name, int d, int c)
        {
            this.name = name;
            this.d = d;
            this.c = c;
        }
    } 
    public static ArrayList<node> list = new ArrayList<>();
    public static int[] pre = new int[maxn];
    public static void  print(int step)        //输出函数  类似 bfs最短路输出路径
    {
        if(step == 0)
            return;
        int t = 0;
        for(int i=0;i<n;i++)
        {
            if((step & (1<<i)) != 0 && (pre[step] & (1<<i)) == 0)
            {
                t = i;
                break;
            }
        }
        print(pre[step]);
        System.out.println(list.get(t).name);
    }
    public static void main(String[] args)  {
        Scanner cin = new Scanner(System.in);
        int cnt = 0;
        int T = cin.nextInt();
        while(T-- != 0)
        {
            list.clear();
            int[] dp = new int[maxn];
            Arrays.fill(pre, 0);
            n = cin.nextInt();
            for(int i=0;i<n;i++)
            {
                String name = cin.next();
                int d = cin.nextInt();
                int c = cin.nextInt();
                list.add(new node(name,d,c));
            }
            Arrays.fill(dp, INF);
            dp[0] = 0;
            for(int i=0;i < 1<<n;i++)  //已经做完的作业
            {
                for(int j=0;j<n;j++)    // 即将要做的作业
                {
                    if((i & (1<<j)) != 0) continue;   
                    int s = 0;
                    for(int k=0;k<n;k++)    //求出已经做完的作业的所耗费的时间  
                    {
                        if((i & (1<<k)) != 0)
                        {
                            s += list.get(k).c;
                        }
                    }
                    if(s + list.get(j).c > list.get(j).d)   //求出即将要做的作业是否超时
                        s = s + list.get(j).c - list.get(j).d;
                    else
                        s = 0;
                    if(dp[i|(1<<j)] > dp[i] + s)   
                    {
                        dp[i|(1<<j)] = dp[i] + s;
                        pre[i|(1<<j)] = i;
                    }
                }
            }
            System.out.println(dp[(1<<n)-1]);
            print((1<<n)-1);
    
        }

    }
}
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
原文地址:https://www.cnblogs.com/WTSRUVF/p/9424583.html