zoukankan      html  css  js  c++  java
  • 【算法竞赛入门经典】7.3子集生成【增量构造法】【位向量法】【二进制法】

    7.3.1增量构造法

    思路:一次选出一个元素放到集合中。自己对于递归的理解还是不够,这里虽然没有明确给出递归停止条件,但是如果无法继续添加元素,就不会再继续递归,然后就是我头疼的回溯啦。

    #include<stdio.h>
    
    int num[4],n;
    
    void A(int n,int *a,int ans)
    {
        for(int i = 0; i < ans; i ++)//打印当前元素 
            printf("%d ",a[i]);
        printf("
    ");
        int s = ans?a[ans-1]+1:0;//确定当前元素的最小可能值 
        for(int i = s; i < n; i ++)
        {
            a[ans] = i;
            A(n,a,ans+1);//递归构造子集 
        } 
        return;
    }
    
    int main()
    {
        n = 3;
        A(n,num,0);
        return 0;
    }

    7.3.2位向量法

    思路:构造一个位向量a[i],如果a[i]=1,当且仅当i在集合子集a中。

    #include<stdio.h>
    int num[4],n;
    
    void print_subset(int n,int *a,int ans)
    {
        if(ans == n)
        {
            for(int i = 0; i < ans; i ++)//打印当前集合 
                if(a[i])
                    printf("%d ",i);
            printf("
    ");
            return;
        }
        a[ans] = 1;//选择第cur个元素 
        print_subset(n,a,ans+1);
        a[ans] = 0;//不选第cur个元素 
        print_subset(n,a,ans+1);
        return;
    }
    int main()
    {
        n = 3;
        print_subset(n,num,0);
        return 0;
    }

    7.3.3二进制法

    #include<stdio.h>
    int n = 3;
    void print_subset(int n,int ans)
    {
        for(int i = 0; i < n; i ++)//打印{0,1,2,3..n-1}的子集ans 
            if(ans&(1<<i))
                printf("%d ",i);
        printf("
    ");
        return;
    }
    
    int main()
    {
        for(int i = 0; i < (1<<n); i ++)//枚举各子集对应的编码 
            print_subset(n,i);
        return 0;
    }
  • 相关阅读:
    编译用到boost相关的东西,问题的解决;以及和googletest库
    看开源代码利器—用Graphviz + CodeViz生成C/C++函数调用图(call graph)
    centos5 升级到centos6
    Go vs Erlang
    Graphviz
    Oracle相关安装经验总结
    学习erlang书籍
    sublime使用总结
    List集合五种遍历方式
    nginx常用命令
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7449400.html
Copyright © 2011-2022 走看看