• 容斥的几种写法


    容斥的几种写法

    容斥公式本身就是 枚举出状态的组合,算其乘积,奇数个值为负,偶数个值为正

    原理:

    对于组合中每个状态有 不在两种,求其组合,可以用二进制枚举,也可以用递归

    1. 二进制
    2. 两层for循环
    3. 递归
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<iomanip>
    #include<map>
    #include<vector>
    #include<time.h>
    #define mset(a,b)   memset(a,b,sizeof(a))
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    const int maxn=1e5;
    const int branch=26;
    const int inf=0x3f3f3f3f;
    const int MOD=1e6+7;
    //假设有tot个数,存储在num数组中
    int num[20];//存放数字种类
    int rc[maxn];//存放容斥的组合
    int tot;//数字种类数
    int cnt;//容斥组合的个数
    void rc_for()//求出num中 tot个数的所有组合
    {
        cnt=0;
        rc[cnt++]=1;//初始状态
        for(int i=0; i<tot; ++i)
        {
            int k=cnt;//下标为i的数与前k个数的所有组合的组合
            for(int j=0; j<k; ++j)
            {
                rc[cnt++]=num[i]*rc[j]*-1;//奇数个为负
            }
        }
    }
    void rc_bit()//用二进制来写
    {
        int top=1<<tot;//共tot个数字
        cnt=0;
        for(int i=0; i<top; ++i)
        {
            int val=1;
            for(int k=0; k<tot; ++k) //枚举每个位是否为1 为1的组合整上去
            {
                if((1<<k)&i)
                {
                    val*=-1*num[k];
                }
            }
            rc[cnt++]=val;
        }
    }
    void dfs(int k,int val)//正在枚举下标为k的状态, 之前组合乘积为-1
    {
        if(k==tot)
        {
            rc[cnt++]=val;
            return ;
        }
        dfs(k+1,val*-1*num[k]);//下标为k的状态在组合中
        dfs(k+1,val);
    }
    void rc_dfs()
    {
        cnt=0;
        dfs(0,1);//
    }
    int main()
    {
        //主要是枚举这些数的所有组合(不能重复)
        /*
        测试
        */
        scanf("%d",&tot);
        for(int i=0; i<tot; ++i)
            scanf("%d",num+i);
        rc_for();
        printf("
    rc_for.........
    ");
        cout<<"cnt:"<<cnt<<endl;
        for(int i=0; i<cnt; ++i)
            printf("%d ",rc[i]);
        puts("");
        printf("rc_bit.........
    ");
        rc_bit();
        cout<<"cnt:"<<cnt<<endl;
        for(int i=0; i<cnt; ++i)
            printf("%d ",rc[i]);
        puts("");
        rc_dfs();
        cout<<"cnt:"<<cnt<<endl;
        for(int i=0; i<cnt; ++i)
            printf("%d ",rc[i]);
        return 0;
    }
    
    
  • 相关阅读:
    增加/删除新用户并添加root权限
    LINUX学习之路-1
    了解参考基因组及注释信息
    RNA-seq操作实战
    如何利用数据库下载参考基因组
    RNA-Seq比对软件HISAT2的用法
    小白-批量下载SRR数据
    sratoolkit 的使用
    批量查看QC结果的工具----multiqc
    fastQC 质控结果解读
  • 原文地址:https://www.cnblogs.com/dchnzlh/p/10427273.html
Copyright © 2020-2023  润新知