【Algothrim】求从n个数中取r个数的组合
来源:互联网 发布:程序设计导论 python 编辑:程序博客网 时间:2024/06/01 21:49
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <iostream>using namespace std;#define MAX 21#define ALL 1100000int edge[MAX][MAX] = { 0 };int Answer = 0;int N, M;int Parent[ALL] = { 0 };int Queue[ALL] = { 0 };void Init(void){int i, j;for (i = 0; i < ALL; i++){Queue[i] = 0;Parent[i] = 0;}for (i = 0; i < MAX; i++){for (j = 0; j < MAX; j++){edge[i][j] = 0;edge[j][i] = 0;}}cin >> N >> M;Answer = N+1;for (i = 1; i <= N; i++){Parent[i] = 0;Queue[i] = i;}for (i = 0; i < M; i++){int a, b;cin >> a >> b;edge[a][b] = 1;edge[b][a] = 1;}}int checksafewithparent(int t, int c){int f = Parent[t];while (f != 0){if (edge[Queue[f]][c]){return 0;}f = Parent[f];}return 1;}void bfs(void){int top = N+1;int bottom = 1;while (top > bottom){int t = Queue[bottom];int i=0;for (i = t+1; i <= N; i++){if ((edge[t][i] == 0) && checksafewithparent(bottom, i)){Queue[top] = i;Parent[top] = bottom;top++;Answer++;}}bottom++;}}int main(void){int test_case;int T;freopen("input.txt", "r", stdin);setbuf(stdout, NULL);scanf("%d", &T);for (test_case = 1; test_case <= T; ++test_case){Init();bfs();cout << "#" << test_case << " " << Answer << endl;}return 0; //Your program should return 0 on normal termination.}
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <iostream>using namespace std;#define MAX 21int edge[MAX][MAX] = { 0 };int Answer = 0;int Data[MAX] = {0};int N, M;void Init(void){Answer = 0;int i,j;for (i = 0; i < MAX; i++){for (j = 0; j < MAX; j++){edge[i][j] = 0;edge[j][i] = 0;}}cin >> N >> M;for (i = 1; i <= N; i++){Data[i] = i;}for (i = 0; i < M; i++){int a, b;cin >> a >> b;edge[a][b] = 1;edge[b][a] = 1;}}int CheckValid(int zh[], int l){int i,j;for (i = 0; i <l; i++){for (j = 0; j < l; j++){if (edge[zh[i]][zh[j]]){return 0;}}}return 1;}void GetAllCombination(int zh[], int start, int end, int index, int r){if (index == r){/*int i;for (i = 0; i < r; i++){cout << zh[i] << "\t";}cout << endl;*/int n = CheckValid(zh, r);//cout << "valid:" << n << endl;Answer += n;return;}if (start + (r - index) > end) return;zh[index] = Data[start];GetAllCombination(zh, start + 1, end, index + 1, r);GetAllCombination(zh, start + 1, end, index, r);}void CalCnts(void){int i;for (i = 1; i <= N; i++){int *zh = new int[i];GetAllCombination(zh, 1, N+1, 0, i);}}int main(void){int test_case;int T;freopen("input.txt", "r", stdin);setbuf(stdout, NULL);scanf("%d", &T);//T = 1;for (test_case = 1; test_case <= T; ++test_case){Init();CalCnts();cout << "#" << test_case << " " << Answer + 1 << endl;}return 0; //Your program should return 0 on normal termination.}
今天做算法题遇到一个问题,涉及到从n个数中求r个数的组合,于是搜了一下。
http://www.acmerblog.com/combinations-of-r-elements-6059.html
给一个数组arr,长度为n,找出从中取出r个数的所有组合。例如对于数组{1, 2, 3, 4} ,r = 2,则打印出:{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4} ,{3, 4}. 也就是 组合公式C(4,2) = 6个。 假设输入的元素没有重复,取出的r个数也没有重复。
使用递归是比较容易解决,类似分治法。组合数有如下的递归关系:C(n,r) = C(n-1, r-1) + C(n-1, r)
上面2个代码,是用来求解n个数字中,m组不能共存,求所有可以共存的种类
代码一: 用上面提到的算法求出所有的组合,然后每个组合遍历一遍,将符合条件的自增
代码二:用BFS,首先全没有是1中,每个数字单独是一种,所以算法开始前Answer就是N+1, 然后用BFS来走,所有可以加到队列里的值都是一种答案
可以用树来理解,根节点是0,第一层是1~N, 再下一层就是与父节点可以共存的点,当决定下一个节点可否入队列时,要遍历从根节点到下面的每一个父节点
这里要注意的是,用来记录父节点的不能是父节点的值,而应该是父节点在队列中的位置,才能唯一标示,不然走着走着就走错了。
阅读全文
0 0
- 【Algothrim】求从n个数中取r个数的组合
- n个自然数中取r个数的组合
- OC----从N个数中选取M个数的组合
- 从n个数中选取m个数的所有组合
- m个数中取n个数的组合
- 从m个数中任意去n个数的组合
- 从1-n中选择m个数的组合个数
- 从自然数1~N里任取R个数的可能组合
- 求组合数: 求n个数(1....n)中k个数的组合
- OC中的组合算法 从N个数里面取M个数的组合
- 从1到N这N个数中取M个数,将这M个数从大到小输出,将所有的组合顺序输出
- 排列组合 从n个自然数中取出r个数的组合
- 两种解法:找出n个自然数(1,2,3,……,n)中取r个数的组合。
- m个数中取n个的组合
- n中任取r个数的所有组合
- 打印从n个数中选取m个数的组合数
- 打印从n个数中选取m个数的组合数
- 递归实现 从n个数中选取m个数的所有组合
- 决策树(decision tree)的自我理解 (上)
- Swift3.0 直接插入排序
- 深入解析String#intern
- iOS开发 二维码扫描和生成
- LeetCode (Binary Tree Preorder Traversal)
- 【Algothrim】求从n个数中取r个数的组合
- [Java算法分析与设计]链式队列的实现
- windows 2008 server 安装VS2010 后无法无法访问数据库,提示“ORA-06413: 连接未打开”
- logback配置
- Android模拟按键
- 【Zookeeper 1】Zookeeper的功能以及工作原理
- JAVA面试 中级
- weblogic管理工具及监控 health state 的方法
- 【集训】jzoj 2017.7.5 noip模拟赛A 总结 (欧拉回路)