2.12 二项式系数加法解 C实现
该问题出自《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 2
n=3 1 3 3 1
杨辉三角程序
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];
}
i = 2时1个加法,i=3时2个加法,i=n时n-1个加法。总共n(n-1)/2个加法。
第三种方法,根据杨辉三角演变出来的
根据杨辉三角演变出来的,但是不按三角形形状顺序进行加法的计算。
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). 可以先计算行也可以先计算列,我们下边按行的顺序相加。
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) |
5 3 c[3] = c[3] + c[2] = 56 C(8,3)
代码如下:
#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;}
2.12 二项式系数加法解 C实现相关推荐
- 我的世界JAVA版有没有混凝土_我的世界1.12混凝土详解 混凝土合成教程
我的世界1.12混凝土详解 混凝土合成教程.我的世界1.12新增加了方块混凝土,今天小编为大家带来了我的世界1.12版新方块混凝土详解和怎样合成的,还不清楚的玩家下面一起来看看吧! 游戏园我的世界官方 ...
- mysql5.7.12 64位解压版_mysql 5.7 64位 解压版安装
64位操作系统最好安装64位的mysql数据库,充分利用内存的寻址能力,对于windows而言,mysql官网只提供了32位的MSI安装程序,因为在windows下安装64位的mysql,选择解压版安 ...
- centos 安装mysql5.6.12_CentOS6.4+MySQL-5.6.12 安装详解
大纲一.安装方式分类 二.具体安装方式详解源码安装 通用二进制包安装 RPM包安装 一.Mysql安装方式分类 1.源码包安装 从MySQL5.5开始就要用cmake安装了,已不能用./configu ...
- 湖南大学夏训练三12.多项式加法
[问题描述] 一个多项式可以表示为一组数对,数对中第一个数始终为整数,且唯一,表示多项式的次数,另一数表示为对应的系数且不为0.输入两组数对,每组以0 0作为结束,实现对两个多项式的加法并按降幂输出结 ...
- pthon3精要(12)-扩展序列解包
y=[1,2,3,4,5,6] x1,*x2=y print(x1) print(x2) z1,z2,z3,z4,*z5=x2 print(z4) print(z5) 1 [2, 3, 4, 5, 6 ...
- 【小白学PyTorch】12.SENet详解及PyTorch实现
<<小白学PyTorch>> 小白学PyTorch | 11 MobileNet详解及PyTorch实现 小白学PyTorch | 10 pytorch常见运算详解 小白学Py ...
- 风影ASP.NET基础教学 12 GridView详解
如果你用过GridView控件后,我相信你会很快喜欢使用它.GridView控件是老版本DataGrid的新一代改良者.是基于DataGrid改良而来的,它不但具备了更强大的数据网格显示与统计等功能, ...
- Rust 12: 面向对象详解(struct + impl + trait)
文章目录 struct impl trait 扩展阅读 总结 struct关键字用于定义一个数据结构,可以类比为面向对象语言中的class. impl关键字可以为struct实现关联的成员方法. tr ...
- 攻防世界新手练习12道题详解(6-12)
六disabled_button 如图: 一个不能按的按钮,所以F12打开查看器,将按钮的disabled=""删除. 删除后,flag按钮显示为可用. 点击得到flag. 七si ...
最新文章
- scrapy 动态IP、随机UA、验证码
- ElementUI在el-table基础上进行导出.xls表格操作
- 第六十期:玩了分布式这么久,你不会连Kafka都不清楚吧
- n1运行linux,斐讯N1折腾记:运行 Linux 及优化
- ThinkPHP---rbac权限管理
- 0.接口测试学习路径
- 大型网站的数据库分割问题。
- python做神经网络有什么框架_神经网络与深度学习——基于TensorFlow框架和Python技术实现...
- vue+node全栈移动商城【4】-创建get、send接口,接收数据更新视图
- Java 开发必须掌握的线上问题排查命令
- live2dmesh渲染优先级_如何渲染Live2D模型
- 单节1A锂电池充电芯片
- 5分钟了解Pandas的透视表
- 如何通过两步验证来保护您的Apple ID
- 域名转换为IP地址示例
- git 小乌龟安装教程
- 【生活常识】如何能安逸的活着?
- JAVA常用基础API(经典实例)
- WBS,工作分解结构
- 全向和定向天线区别,何为天线增益