-
2012-09-19 20:12:22
请写一个程序,求出n中取r个的组合系数C(n,r)
首先,根据C(n,r)的定义求解,不难得出解法如下:
unsigned long cnr(int n, int r) { if (n < 0 || r < 0) return 0; unsigned long numerator = 1; unsigned long denominator = 1; for (int i = 0; i < r; i++) numerator *= (n - i); for (int i = 1; i <= r; i++) denominator *= i; return numerator / denominator; }
利用公式C(n,r)=C(n-1,r-1)+C(n-1,r)来化简求解:
#include <iostream> using namespace std; #define MAXSIZE 100 unsigned long cnr(int n, int r) { unsigned long c[MAXSIZE]; int i, j; for (i = 0; i <= r; i++) c[i] = 1; for (i = 1; i <= n - r; i++) for (j = 1; j <= r; j++) c[j] += c[j - 1]; return c[r]; } void main() { int result = cnr(10, 2); cout << "result = " << result << endl; }
快速二项式系数算法:
利用公式 (2^p + 1)^n = C(n,0) + C(n,1)2^p + C(n,2)(2^p)^2 + ... + C(n,n)(2^p)^n,只用于logn成正比的乘法次数求所有C(n,i),i=0,1,...,n的办法吗?
#include <iostream> #include <iterator> #include <algorithm> using namespace std; #define MAXSIZE 100 unsigned long answer[MAXSIZE]; unsigned long long int power(unsigned long base, unsigned long exp) { unsigned long long int result = 1; while (exp) { if (exp & 0x01) result *= base; base *= base; exp >>= 1; } return result; } void cnr(unsigned long n, unsigned long *answer) { unsigned long long int x = (1 << n) + 1; unsigned long long int mask = (1 << n) - 1; unsigned long long int result; result = power(x, n); for (unsigned long i = 0; i <= n; i++, result >>= n) { cout << result << endl; answer[i] = result & mask; cout << "answer[" << i << "] = " << answer[i] << endl; } } void main() { int number = 4; cnr(number, answer); copy(answer, answer + number, ostream_iterator<int>(cout, " ")); }
采用上面的思想确实很NB,但是该方法存在一个问题,由于result的值很大导致容易溢出。。。
更多相关内容 -
链表法求二项式加法的一种解法
2009-05-24 17:12:45你可以自己输入自己输入数字,求二项式加法 -
每日一小练——二项式系数加法解
2014-05-22 14:12:01题目:二项式系数加法解 内容:请编写一个程序,只用加法,求出n中取r个组合系数C(n,r),并且尽可能地使加法数目降低。 关于二项式:在数学里,二项式系数,或组合数,是定义为形如(1...上得厅堂,下得厨房,写得代码,翻得围墙,欢迎来到睿不可挡的每日一小练!
题目:二项式系数加法解
内容:请编写一个程序,只用加法,求出n中取r个组合系数C(n,r),并且尽可能地使加法数目降低。
关于二项式:在数学里,二项式系数,或组合数,是定义为形如(1 + x)的二项式n次幂展开后x的系数(其中n为自然数,k为整数),通常记为。从定义可看出二项式系数的值为整数。这是来自百度的定义。我就不再赘余了。
关于二项式系数我们有一条性质使我们可以使用递归形式:
C(n,r)=C(n,r-1)+C(n-1,r-1)
所以写出递归代码
#include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { int c(int n, int r); cout << c(8,3)<<endl; getchar(); return 0; } int c(int n, int r) { if (n == r || r == 0) { return 1; } else { return c(n - 1, r) + c(n - 1, r - 1); } }
根据我们老祖先发明的杨辉三角的性质我们也可以写出非递归的形式
#include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { int c(int n, int r); cout << c(8,3)<<endl; getchar(); return 0; } int c(int n, int r) { int result[1000]; int i, j; result[0] = 1; for (i = 1; i <= n; i++) { for (result[i] = 1, j = i - 1; j >= 1; j--) { result[j] += result[j - 1]; } } return result[r]; }
不过其实上面两种方法都不是加法使用最少的方式,最少的方式是通过排列递归路线,如图
图中给出了C(8,3)的运算递归路线,每个下顶点都是由上两个顶点加和,所以我们可以重新排列加法顺序,使得加法按行进行,便可节省近三分之一的加法运算效率很好。
实现代码如下:
#include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { int c(int n, int r); cout << c(8,3)<<endl; getchar(); return 0; } int c(int n, int r) { int result[1000]; int i, j; for (i = 0; i <= r; i++) { result[i] = 1; } for (i = 1; i <= n - r; i++) { for (j = 1; j <= r; j++) { result[j] += result[j - 1]; } } return result[r]; }
三段程序的实验结果相同:
欢迎大家加入每日一小练,嘿嘿!
每天练一练,日久见功夫,加油!
-End-
参考文献:《c语言名题精选百则》
-
高中数学必修三排列组合二项式定理概率加法公式PPT学习教案.pptx
2021-10-03 19:31:27高中数学必修三排列组合二项式定理概率加法公式PPT学习教案.pptx -
组合数学实验 Fibonacci数列 二项式系数的加法求解
2009-07-13 22:00:44实验一、Fibonacci数非递归解 Fibonacci数列 的定义如下: 请用递归方法和非递归方法求解该问题,各编写一个函数,要求函数接受 的值,返回 的值。两个程序实现后,分别求 的情况,对比两个程序的执行时间,然后... -
2.12 二项式系数加法解 C实现
2015-01-22 18:21:36由二项式性质的(2)和(3)很容易想到A(n,r) = C(n,r) -1 = n(n-1)...(n-r+1)/[r(r-1)...*3*2*1]-1.与n^r成正比。 第二种方法:杨辉三角(Pascal) n=0 1 n=1 1 1 n=2 1 2 2 n=3 1 3 3 1 杨辉...该问题出自《C语言名题精选百则技巧篇》
题目:编写一个程序,只用加法,求出n中取r个的组合系数C(n,r),并且尽可能的使加法数目降低。
我们先来了解一下二项式系数的性质:
(1) C(m,n) = C(n,n-m)
(2) C(n,r) = C(n-1,r)+C(n-1,r-1)
(3) C(n,0) = 1,C(n,1) = n, C(n,n) = 1
第一种方法:递归函数
我们来分析一下,上面这种方法用到的加法的个数。int cnr(int n,int r) { if(n==r || r ==0) return 1; else return cnr(n-1,r)+cnr(n-1,r-1); }
用A(n,r)表示在计算C(n,r)时所用到的加法的个数,从if部分看,当n=r以及r=0时没有用到加法,因此A(n,n) = A(n,0) = 0;从else的部分看,要先计算C(n-1,r)和C(n-1,r-1), 一共用了A(n-1,r)和A(n-1,r-1)个加法,最后又多了一个加法,因此A(n,r)可以表示为:
A(n,r) = 0 n==r或者r==0
A(n,r) = A(n-1,r)+A(n-1,r-1)+1.
由二项式性质的(2)和(3)很容易想到A(n,r) = C(n,r) -1 = n(n-1)...(n-r+1)/[r(r-1)...*3*2*1]-1.与n^r成正比。
第二种方法:杨辉三角(Pascal)
n=0 1
n=1 1 1
n=2 1 2 2n=3 1 3 3 1
杨辉三角程序
i = 2时1个加法,i=3时2个加法,i=n时n-1个加法。总共n(n-1)/2个加法。int cnr(int n,int r) { int answer[MAXSIZE]; int i,j; answer[0] =1; for(i=1;i<=n;i++) for(answer[i]=1,j=i-1;j>=1;j--) answer[j]+=answer[j-1]; return answer[r]; }
第三种方法,根据杨辉三角演变出来的
根据杨辉三角演变出来的,但是不按三角形形状顺序进行加法的计算。
C(0,0) C(1,1) C(2,1) C(3,3)
C(1,0) C(2,1) C(3,2) C(4,3)
C(2,0) C(3,1) C(4,2) C(5,3)
C(3,0) C(4,1) C(5,2) C(6,3)
C(4,0) C(5,1) C(6,2) C(7,3)
C(5,0) C(6,1) C(7,2) C(8,3)
先把所有元素都初始化为1,从C(2,1)开始,每一个元素等于它的左边的元素和上边的元素的值相加。所以一共只需要加15次就可以得到结果C(8,3). 可以先计算行也可以先计算列,我们下边按行的顺序相加。
5 3 c[3] = c[3] + c[2] = 56 C(8,3)i j c[j] 对应 1 1 c[1] = c[1] +c[0] =2 C(2,1) 1 2 c[2] = c[2] +c[1] =3 C(3,2) 1 3 c[3] = c[3] +c[2] = 4 C(4,3) 2 1 c[1] = c[1] +c[0] = 3 C(3,1) 2 2 c[2] = c[2] +c[1] =6 C(4,2) 2 3 c[3] = c[3] +c[2] =10 C(5,3) 3 1 c[1] = c[1] +c[0] = 4 C(4,1) 3 2 c[2] = c[2] + c[1] = 10 C(5,2) 3 3 c[3] = c[3] + c[2] = 20 C(6,3) 4 1 c[1] = c[1] +c[0] = 5 C(5,1) 4 2 c[2] = c[2] + c[1] = 15 C(6,2) 4 3 c[3] = c[3] +c[2] = 35 C(7,3) 5 1 c[1] = c[1] + c[0] = 6 C(6,1) 5 2 c[2] = c[2] + c[1] =21 C(7,2)
代码如下:#include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 unsigned long cnr(int n,int r) { unsigned long c[MAXSIZE]; int i,j; for(i=0;i<=r;i++) c[i] = 1UL; for(i=1;i<=n-r;i++) for(j=1;j<=r;j++) c[j]+=c[j-1]; return c[r]; } int main(int argc,char *argv[]) { int n,r; unsigned long answer; printf("\nCnr Program:m^n"); printf("\nInput n -->"); scanf("%d",&n); printf("\nInput r -->"); scanf("%d",&r); answer = cnr(n,r); printf("The answer of Cnr is:Cnr = %ld",answer); while(1) getchar(); return 0; }
-
二项式系数加法解 + 快速阶乘运算
2014-02-13 12:04:53偶然看见的东西,感觉还是挺厉害的。...二项式系数加法解 - alexingcool的专栏 - 博客频道 - CSDN.NET 快速阶乘运算 - alexingcool的专栏 - 博客频道 - CSDN.NET 补充:斯特灵公式求阶乘:对于足够大的n偶然看见的东西,感觉还是挺厉害的。
主要用到的公式是
二项式系数加法解 - alexingcool的专栏 - 博客频道 - CSDN.NET
快速阶乘运算 - alexingcool的专栏 - 博客频道 - CSDN.NET
补充:斯特灵公式求阶乘:对于足够大的n
-
二项式定理与复数
2017-08-03 08:23:00(加法定理)若 , 则 的极坐标是 (棣莫弗定理)对每个实数和每个正整数n,有 数学归纳法证明 (欧拉定理)对所有实数,有 用三角级数和e的展开式来证明 定义 设是整数,若复数... -
使用并行前缀加法和二进制到多余的1转换的混合进位选择加法器的有效实现-研究论文
2021-05-19 21:22:04加法器是将二进制数字加在一起的数字逻辑设备。 它们通常用作算术逻辑单元的组件,而算术逻辑单元本身就是中央处理单元的组件。 结果,任何具有微控制器或CPU的电子设备,例如智能恒温器,数字闹钟,数字手表和数字... -
C语言:巧用杨辉三角求二项展开式的系数
2016-01-06 23:45:08巧用杨辉三角求二项展开式的系数标签: C语言 杨辉三角 二项式展开式by 小威威1.引入我们知道,求二项式展开式系数可根据牛顿的二项式定理,即利用组合数求系数。其实,二项式展开式系数其实也是满足杨辉三角的。在... -
二项式定理(Java实现及代码重审)
2011-04-22 17:33:00在上一篇文章中,我总结了从阅读《编程珠玑I》中获得的一些启示。... 作为代码重审和回顾的一个例子,我对以前的一个粗糙的二项式定理实现进行了重审和改写。当时,主要是为了学习动态规划法技术,运 -
动态规划 — 计算二项式系数
2014-06-09 19:40:09从上面的递推式可以看到两个较小的具有交叠性质的子问题C(n-1,k-1)和C(n-1,k),所以,计算二项式系数是把动态规划应用于非最优化问题的一个标准例子。 废话不多说,直接上代码: #include #... -
Verilog练习二【串行加法器】(附公式推导)
2020-04-30 23:04:19串行加法器由多个1位全加器串联构成,如下图所示,每个1位全加器包含3个输入和两个输出,其中c[i]是进位输出。 根据上图,列出1位全加器的真值表: A B Ci So Co 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 ... -
求出n中选r个的组合系数c(n,r),只用加法实现 即 求二项式系数(杨辉三角),
2013-06-17 21:59:11求二项式系数(杨辉三角), 求出n中选r个的组合系数c(n,r),只用加法实现 我写的算法,加法效率漏了点。。。 ''' def ComputCnr(n, r): listArr=[0]*(r+1) #python有类似动态存储分配的,挺不错的 if r>=n/2: ... -
C算法与数据结构-线性表的应用,多项式求和---ShinePans
2014-05-08 21:12:42/*---上机作业作业,二项式加法---*/ /*---By 潘尚 ---*/ /*---日期: 2014-5-8 . ---*/ /*---题目:---*/ //假设有两个稀疏多项式A和B,设计算法完成下列任务 //1.输入并建立多项式A和B; //2.求两个多项式的和多项式C; ... -
超前进位加法器设计报告
2021-01-13 23:31:16华东交通大学理工学院课 程 设 计 报 告 书所属课程名称 EDA 课程设计 题 目分 院专业班级学 号学生姓名... 3第二章 超前进位加法器设计原理 ................................ 3第三章 详细设计流程 .............. -
概率论3——古典概型与二项分布
2020-09-23 16:44:191}p=(\frac{N-K}{N})^{r-1}(\frac{K}{N})P(r)=(1−p)r−1p=(NN−K)r−1(NK) 二项分布 上面的抽样方式中,利用第四种放回无序的抽样,在对立事件的集合中,可以得到二项分布: 1、集合必须右对立事件构成,比如一... -
超前进位加法器
2020-12-23 12:45:40首先画出2位全加器的真值表与卡诺图根据真值表可知二进制加法与十进制加法一样,进位值是逢二进一.而和值则是上级进位值跟被加数跟加数总和模二的余数.根据卡诺图化简得到S与Ci+1的全加器电路为:多位加法器可以用行波... -
数据结构课程设计—一元多项式加法、减法、乘法运算的实现
2021-05-20 08:34:00《数据结构课程设计—一元多项式加法、减法、乘法运算的实现》由会员分享,可在线阅读,更多相关《数据结构课程设计—一元多项式加法、减法、乘法运算的实现(20页珍藏版)》请在人人文库网上搜索。1、1.一元多项式... -
累加法
2019-03-27 10:53:00求通项公式题型中,如果给定条件最终可以转化为\(a_{n+1}-a_n=f(n)\)的形式,或者可以转化为\(a_n-a_{n-1}=f(n)\)的形式,则我们就可以考虑使用累加法求通项公式。 一、注意事项 ①由已知的原始表达式衍生出\(n-1\)... -
加法器MATLAB代码-University-Notes:笔记以及与我在UoE学习相关的课程资料库的链接
2021-06-01 22:25:47加法器MATLAB代码大学档案 免责声明 此处包含的任何课程或私人文件均已过期。 我不会分享任何截止日期尚未通过的课程文件 概述 这个存储库曾经包含我所有的大学文件,包括课程作业。课程作业已被提取到单独的存储库... -
实现加法器>koggle-stone加法器设计——超前进位加法器改进
2021-04-29 23:49:31加法器是数字电路中的最基础电路之一,也是CPU的核心功能之一。 在这个专栏,我会把所有我知道的数字电路的加法器相关模型都实现一遍并解释其原理。 编程使用的语言为Verilog,代码风格为强迫症系列风格。 加法器... -
四位并行加法器设计
2021-07-16 04:33:10《四位并行加法器设计》由会员分享,可在线... E20814108、E20814098 学生姓名: 蒋 信、许 东 年级专业:08软件工程二班 授课教师: 周 勇 老 师 完成时间: 2011/03/20 4位并行加法器设计实验1 课程设计概述1.1 课... -
实现加法器>brent-kung加法器设计——超前进位加法器改进
2021-04-30 08:41:13加法器是数字电路中的最基础电路之一,也是CPU的核心功能之一。 在这个专栏,我会把所有我知道的数字电路的加法器相关模型都实现一遍并解释其原理。 编程使用的语言为Verilog,代码风格为强迫症系列风格。 加法器... -
离散基础 (12). 二项恒等式
2017-05-04 15:27:221. 基础知识2. 对称恒等式3. 吸收恒等式4. 加法恒等式5. 乘法恒等式 -
杨辉三角与二项式定理(排列与组合) By ACReaper
2013-04-21 16:19:55由帕斯卡恒等式我们可以很轻易的总结出杨辉三角形的规律,其实这个三角形也叫帕斯卡三角形。 帕斯卡i恒等式: 即(n + 1)(k) = (n)(k) + (n)(k - 1),这个恒等式很好证明也很容易理解,...要么不选,根据加法定理就有(n -
二项堆与斐波那契堆
2017-06-28 19:48:04二项堆 二项堆是符合最小堆性质的二项树链接成的森林二项树是形如下图的树 -
《组合数学引论(第2版)》作者: 许胤龙、孙淑玲 出版年: 2010年
2019-05-17 20:37:38全书共分10章:鸽巢原理,排列与组合,二项式系数,容斥原理,生成函数,递推关系,特殊计数序列,Polya计数理论,相异代表系,组合设计。取材的侧重点在于体现组合数学在计算机科学特别是在算法分析领域中的应用。... -
C语言实现一元多项式的加法与乘法
2022-04-06 15:04:54文章目录问题描述一、程序结果二、实现步骤与程序说明1.问题分析2.代码结构主函数:链表的插入多项式的创建多项式加法多项式乘法多项式的输出三、总结 问题描述 题目来源:PTA 数据结构与算法题目集(中文)7-2 ...