一道数字排列组合生成器题,思考的方式是什么?

一道排列组合题
已有 1043 次阅读
|个人分类:|系统分类:|关键词:排列 组合 二项式
今天在群里看见一道题,共5个按钮,对应5种动物。每个按钮按一下出现一种动物。再按一下出现第二只这个动物。按钮每个只能按2次,5个按钮随机按。求最后能产生多少个不同的画面。是美工,数学应该也不怎么样,做了40几个以后发现不对劲了,效率怎么这么低?于是就进群求教。我算了两次,推出的第一个公式是::$\prod_{i=1}^{n-1}{((2i+1)+B[2i+1,2])}$ 这个公式看不懂没事,后面有更简单的。看上去有点复杂,但其实很好理解,我们用数字来表示动物好了。1个按钮不一定照先1后2的顺序,所以有3个空位留给第2个按钮,就像这样子:括号内可以是个2或个2。那么就有$3+B[3,2]=6$种情况,我们用abcd表示,于是第3个按钮就有5个空位了,就像这样子:( )a( )b( )c( )d( )括号内可以是两个3或个3。那么就有$5+B[5,2]=15$种情况。abcd有6种情况,所以,共计 15*6=90 种情况。依次类推,出现的情况依次是:2个按钮有6种情况,是4!的1/4。3个按钮有15*6=90种情况,是6!的1/8。4个按钮有28*15*6=2520种情况,是8!的1/16。5个按钮共计45*28*15*6=113400种情况,恰好是10!的1/32。引入阶乘是由于担心重复计算导致可能性超结果却发现了这一巧合,这就说明n个按钮,有 (2n)!/2n。(2n)!种情况,但有2个动物是重复的,一共有n组,所以要除以2n。,那么就有可能按出1122这种情况。但4!里还包括了:1122,1122,1122。所以要除以2。这种思路就算一开始没想到,做过一遍以后也就有了。这种题做的过程中有一种探究未知的兴奋,但做完了以后,又觉得挺一般的。其实解题过程就如同做爱,射了以后,就会觉得很空虚。乙方倒也不在乎具体的结果,她的意思是超过100个就不想做了,何况是11万个。---------------7.28修改:1.Binomial是二项式系数,以前高中学的时候用的是C,现在貌似用B了。$B[2i+1,2]=\frac{(2i+1)*2i}{2}$2.利用上式证明下面的式子并不难。$\prod_{i=1}^{n-1}{((2i+1)+B[2i+1,2])}=\frac{(2n)!}{2^n}$3. $\frac{(2n)!}{2^n}$ 把偶数项的2约掉,会变成 $n!\prod_{i=1}^{n-1}{(2i+1)}$这个公式也能对应一个解题思路:,2345,5只有1个空位,3 4 5后,4,3 45 )5)放哪里,3都有5个空位可呆,34 ))5 & & )5)345 )5)345 & & )5)以此类推,2有7个空位,1有9个空位。$n=5$时,9*7*5*3对应的就是$\prod_{i=1}^{n-1}{(2i+1)}$
转载本文请联系原作者获取授权,同时请注明本文来自科学网博客,链接地址:
上一篇:下一篇:
当前推荐数:3
评论 ( 个评论)
扫一扫,分享此博文
作者的精选博文
作者的其他最新博文
热门博文导读
Powered by
Copyright &排列组合问题的类型及解答策略
排列组合问题的类型及解答策略
325__________
12341234124331331=9B
1028171=2520C
012345=300B
U={64}A={}B={}
1234_________
10464436634=141D小学课件初中课件
小升初卷 中考试题
学习方法 试卷分析
谈排列组合应用题的教学
导读:排列组合应用题思维抽象,解法独特且灵活多变,搞好排列组合应用题的教学对训练学生的思维,培养学生分析问题、解决问题的能力都有十分重要的意义。加法原理和乘法原理是推导排列组合种数计算公式的重要依据,也是解排列组合问题的关键。推导排列组合公式要用两个原理,解决排列组合应用题也要用“两个原理”,因此在排列组合内容的教学中应把“两个原理”的教学贯穿始终。关键词:排列,组合,应用题排列组合应用题思维抽象,解法独特且灵活多变,搞好排列组合应用题的教学对训练学生的思维,培养学生分析问题、解决问题的能力都有十分重要的意义。那么,如何搞好这部分内容的教学呢?笔者结合自己多年的教学经验谈几点体会。一、抓住“两个原理”1.重视对“两个原理”的教学。“加法原理”和“乘法原理”是推导排列组合种数计算公式的重要依据,也是解排列组合问题的关键。授课时应结合实际多举些例子,让学生明确哪一类问题用“加法原理”,哪一类问题用“乘法原理”;让学生明确在考虑应用两个原理解决问题时,要注意“完成一件事”的办法是分步进行还是分类完成。如果是分步进行,就找出完成每一步的方法数,运用乘法原理来解决;如果是分类完成的,就找出每一类的方法数,运用加法原理来解决。例1:有五个球要放在三个盒中,共有多少种不同的放法?此问题的关键是5个球都要放到盒中,而每个球都有3种放法,把其中某个球放到盒中是完成“5个球放到盒中”这件事的一个步骤,只有5个步骤全部完成这件事才算完成,按乘法原理有3×3×3×3×3﹦﹦245(种)例2:从甲地到乙地每天有1班火车,2班轮船,4班汽车。王红要从甲地到乙地,乘坐这三种交通工具一天有多少种不同走法?此问题的关键是王红无论乘火车、乘轮船还是乘汽车都能完成从甲地到乙地这件事,且乘火车有1种方法,乘轮船有2种方法,乘汽车有4种方法,按加法原理有1+2+4﹦7(种)2.贯穿“两个原理”于教学始终。推导排列组合公式要用“两个原理”,解决排列组合应用题也要用“两个原理”,因此在排列组合内容的教学中应把“两个原理”的教学贯穿始终。每解一道题都要注意分析“完成一件事”是分步还是分类,进而明确是用加法原理还是用乘法原理。经过经常化训练,慢慢地学生就会对“两个原理”运用自如了。二、辨清“排列”“组合”在解排列组合应用题时,在明确了使用哪个原理的同时,还要提醒学生注意分辨是排列问题还是组合问题。排列是按一定顺序排成的一列元素,两个排列的不同,意味着两个排列的元素不同或元素相同,但元素的排列顺序不同。组合是无顺序约束的一组元素,两个组合的不同,意味着当且仅当两个组合元素的不同。要辨清所解问题是排列还是组合,主要看这个问题与元素的排序有无关系,有关是排列问题,无关是组合问题。例3:用1分、2分、5分的硬币各一枚,可以组成多少种不同的币值?三种硬币组成不同币值的方式可分为三类,即分别用一枚两枚三枚组成,且无论用几枚硬币所组成的币值种数与硬币的排序无关,因此是组合问题,共++﹦7(种)例4:某信号兵用红、黄、蓝三面旗,从上到下插在竖直的旗杆上表示信号,每次可插一面、两面、三面,一共可以表示多少种不同的信号?解此类问题时要求学生联系实际。挂旗表示信号,与各色旗的上下顺序有关,因此是排列问题。信号又可分为三类,用一面旗、两面旗、三面旗都可独立表示不同信息,因此有++﹦15(种)三、总结常用方法讲排列组合应用题时,教师不要急于教给学生解各类问题的方法,可先让学生广开思路,从不同角度分析问题,再把学生的解题方法汇集起来,然后让大家讨论,哪种方法巧妙,哪种方法带有一般性,是常用方法。经归纳总结,解排列组合应用题有以下几种常用方法。1.直接法。就是根据题中的约束条件,直接使用两个原理,从正面求出符合题意的排列(组合)种数。例5:五人并排照相,甲必须在中间有多少种不同排法?解:假设有排好了顺序的五个位置,不考虑甲,先在四个人中选一人站在一号位,再从其余的三人中选一人站在二号位,三号位留给甲,四号位从余下的二人中选,剩下的1人就是五号位了。共有排法﹦24(种)。也可从把除甲外的四人全排,在每一种排法中让甲站在中间有﹦24(种)。 2.间接法。就是从不考虑约束条件的排列(组合)中剔除不符合约束条件的排列(组合)种数。如例5的间接求法。 解:把5个人的全排列剔除甲不在中间位置的排法,有-4﹦24(种)。3.特殊元素优先法。排列组合问题中有些元素有一定的特殊约束条件,求解时先考虑有特殊约束条件的元素。如例5,甲是有特殊约束条件的元素,所以先把甲放在中间位置,其余4人在另外四个位置任意排列,有﹦24(种)。4.捆扎法(或并元法):排列问题中往往要求某些元素必相邻。解这类问题时可把这些元素捆扎在一起并作一个元素加以排列例6:5个人并排照相,甲乙二人不分开有多少种不同的排法?解:可分两步。①把甲乙二人捆扎在一起看作一个元素与其余三人进行全排列,有种,②再把甲乙二人全排列有种,由乘法原理有﹦48种。5.插空法。排列题经常有某两个元素不相邻的排法。解题时可先排无约束元素,再把有约束元素插在已排好顺序的空中。例7:5个人排成一排照相,甲乙两人不相邻有多少种排法?解:分两步:①先把其余三人全排,有种,②三人排好后有4个空可插,甲乙任选二空有种,由乘法原理有﹦72种。6.先组后排法。有些数列可通过先组合后排列两步完成。例8:从1、3、5、7、9中取三个数字,从2、4、6、8中取两个数字,共能组成多少个无重复数字的五位数?解:分三步:①从1、3、5、7、9中取三个数不考虑顺序,有种取法,②从2、4、6、8中取两个数亦不考虑顺序,有种取法,③对取出的五个数进行全排列有种,由乘法原理共有﹦7200种。7.集合法。就是把排列组合当做集合,用集合的性质及元素个数计算公式来求解。例9:某一天的课表要排入政治、语文、数学、物理、体育五节课。如果第一节不排体育,第五节不排数学,一共有多少种不同的排法?解:设全集为,集合A﹦,集合B﹦,则﹦,﹦,﹦,﹦,则符合题意要求的排列法种数为:﹦+-﹦+-﹦(-)+(-)-(-)﹦-2+﹦78(种)教师在帮助学生归纳出以上几种常用方法后应指出:在解排列组合应用题时要广开思路,不能死记硬背硬套方法,要善于变通,因为有时一道题可能要用到几种方法,所以只有把方法吃透,才能用法得当。四、检验答案排列组合应用题种类繁多,思维抽象,一般的答案数较大,学生做完题后往往对答案正确性把握不大。在教学过程中教师应教会学生检查答案的方法。1.列举法:对元素个数较小的排列组合问题可把符合约束条件的排列或组合一一列举检验。2.缩数法:对元素个数较多的排列组合可用类比的方法缩小元素个数再用列举法检验。3.多解法:对同一题用两种或两种以上方法计算易于判断答数正误。4.讨论法:对实在没把握的问题可相互讨论,采长补短,发现问题,求得正确答数。总之,在排列组合应用题的教学中,教师要引导学生在做题前一定要认真审题、慎密思考,分清“完成一件事”是过程分步还是方法分类;是排列问题还是组合问题。经过训练,由单一到综合,由简单到复杂,再难的问题也可以解决了。
与"谈排列组合应用题的教学"相关文章
网友最近关注
数学论文推荐内容
数学论文热门排行榜  一、问题的提出   问题 甲、乙、丙、丁四人排成一排,甲不排首位,乙不排在第二位,丙不排在第三位,丁不排末位," />
免费阅读期刊
论文发表、论文指导
周一至周五
9:00&22:00
一道排列组合试题的求解及推广
2013年第1期目录
&&&&&&本期共收录文章5篇
  一、问题的提出 中国论文网 /9/view-4795055.htm  问题 甲、乙、丙、丁四人排成一排,甲不排首位,乙不排在第二位,丙不排在第三位,丁不排末位,共有 种不同的排法.   这是一道简单的填空题,但很多学生出错,甚至毫无解题头绪.笔者在进行解答之后有意识地对它加以推广,得出了一个一般性的结论.这是我的解题心得,而且在推广这个命题时有个惊奇发现:这个结论与二项式定理竟然有着惊人的相似之处,真是太巧合了,这也是我写这篇论文的原因之一.   二、问题的解法   (一)直接法   分析:第一位不排甲,则第一位排乙、丙、丁之一,有3种排法.设第一位排乙,甲可排在第二或第三或第四位.若甲排第二位,则丙、丁只能分别排在第四和第三位,仅有1种排法,若甲排在第三或第四位情况也一样.故总的排法数是3×(1+1+1)=9(种).   上述解法是直接法,由于人数较少,这个解法简单易懂.但我们不禁要问:能否用间接法求解呢?如果排队的人数更多,那直接法是不是还很方便呢?   (二)间接法   为了探求用间接法求解,我们可以采取以退为进的策略:即先减少要排列的人数,通过设置一系列小问题并逐个加以解决,来得出这个问题的方法数,然后把排列人数加以推广,并最终得出这类问题的一般性结论.   问题1 甲、丁两人排成一排,甲不排首、丁不排尾,有几种不同的排法?   解:不考虑限制条件共有A22种排法.甲站在排头、丁站在排尾,各有A11种排法,应减去,但这里甲站在排头的A11种排法和丁站在排尾的A11种排法包含了“甲站在排头、丁站在排尾”的情形(有A11种,不妨写成A00)必须加回,即共有:A22-2A11+A00=1(种)排法.   问题1所排列的人数只有两人,解法容易理解.   引例1 甲、乙、丁三人排成一排,甲不在排头、丁不在排尾、乙一定排在第二位,有几种不同的排法?   解:此问题等价于问题1,共有A22-2A11+A00=1(种)排法.   引例2 甲、乙、丁三人排成一排,甲不在排头,丁不在排尾,有几种不同的排法?
转载请注明来源。原文地址:
【xzbu】郑重声明:本网站资源、信息来源于网络,完全免费共享,仅供学习和研究使用,版权和著作权归原作者所有,如有不愿意被转载的情况,请通知我们删除已转载的信息。
xzbu发布此信息目的在于传播更多信息,与本网站立场无关。xzbu不保证该信息(包括但不限于文字、数据及图表)准确性、真实性、完整性等。问题建议修改
建议修改原因:问题表意不明
请将问题表述完整,消除歧义。让其他人准确理解你的提问是获得回答的前提。
一道排列组合的问题,求出所有的排列组合方式?
已知一段长度为11字符串由数字和字母组成,求出所有的排列组合方式,这样的一段代码怎么写?感觉写的效率太低了.1、可以重复,如:
、111111aaaaa2、区分大小写3、全部的排列组合有 62^11 =
种情况(开始算错了)我也不知道为什么要写这么多..............
按投票排序
3. 你算错了,是 62^11 = #include &stdio.h&
#include &string&
#include &vector&
using std::string;
using std::vector;
class Counter
Counter(const string& alphabet, int digits)
: alphabet_(alphabet),
radix_(alphabet.size()),
digits_(digits),
number_(digits),
value_(digits, alphabet[0]),
done_(false)
const string& value() const { return value_; }
bool done() const { return done_; }
void inc()
int digit = 0;
while (digit & digits_)
if (number_[digit] == radix_ - 1)
number_[digit] = 0;
value_[digits_ - digit - 1] = alphabet_[number_[digit]];
number_[digit]++;
value_[digits_ - digit - 1] = alphabet_[number_[digit]];
if (digit == digits_) done_ = true;
const string alphabet_;
const int radix_;
const int digits_;
vector&int& number_;
string value_;
bool done_;
int main()
Counter cnt("ABCDEFGH", 4);
while (!cnt.done()) {
printf("%s\n", cnt.value().c_str());
cnt.inc();
11个循环嵌套,每个循环跑26+10次。。。还能咋办呢?
import 大法好。
import itertools
import string
alphabet = string.ascii_letters + string.digits
repeat = 4
# 11 too large, use 4 to test
print '\n'.join(map(''.join, itertools.product(*([alphabet] * repeat))))
可以去使用深度优先搜索
题主你之前是怎么写的?为啥会感觉效率低?
用11个循环确实是太傻了。这种问题最重要的应该是拓展性,直接看代码吧。JAVA。package zhihu;
import java.util.*;
public class Q {
public static void main(String[] args) {
Iterator&String& i = new Arrangement(5, 'a', 'b', 'c', '1');
i.forEachRemaining(System.out::println);
class Arrangement implements Iterator&String& {
private final int maxIndex;
private final int[] used;
private final char[] chars;
public Arrangement(int digit, char... chars) {
this.maxIndex = chars.length - 1;
this.used = new int[digit];
this.chars = Arrays.copyOf(chars, chars.length);
public boolean hasNext() {
for (int i : used)
if (i != maxIndex)
return true;
return false;
public String next() {
StringBuilder sb = new StringBuilder();
for (int i : used)
sb.append(chars[i]);
return sb.toString();
private void use() {
for (int i = used.length - 1; i &= 0; i--) {
if (used[i] == maxIndex)
used[i] = 0;
used[i]++;
写11个循环的这代码也太不可扩展了
class IndexesIterator implements Iterator&int[]& {
private int[] caps;
private int[] currents;
private boolean nextAvailable;
public IndexesIterator(int[] caps) {
Preconditions.checkNotNull(caps, "caps can't be null");
Preconditions.checkArgument(caps.length & 0, "caps length must & 0");
this.caps = Arrays.copyOf(caps, caps.length);
this.currents = new int[caps.length];
nextAvailable = true;
for (int i = 0; i& caps.length; ++i) {
if (currents[i] &= caps[i]) {
nextAvailable = false;
public boolean hasNext() {
return nextAvailable;
public int[] next() {
if (!nextAvailable) {
throw new RuntimeException("No more elements");
int[] results = Arrays.copyOf(currents, currents.length);
for (int i = caps.length - 1; i &= 0; --i) {
if (++currents[i] & caps[i]) {
nextAvailable = true;
currents[i] = 0;
if (i == 0) {
nextAvailable = false;
return results;
#include &algorithm&bool next_permutation( iterator start, iterator end );
Java代码:
* 允许重复的全排列
* @param dict
字典。不允许包含重复元素。
* @param permLength
排列的长度。
public static void permutationWithRepetion(char[] dict, int permLength) {
if (dict == null) {
throw new IllegalArgumentException("Argument dict cannot be null.");
if (containsDuplicate(dict)) {
throw new IllegalArgumentException(
"Argument dict cannot contain duplicate elements.");
if (permLength & 1) {
throw new IllegalArgumentException(
"Argument permLength cannot be less than 1.");
Arrays.sort(dict);
char[] permutation = new char[permLength];
permutation(dict, permutation, 0);
* 遍历字典,排列的第 permIndex 个位置设置为字典中的元素,并且递归生成 permIndex 位置后面的部分。
* @param dict
* @param permutation
正在生成的排列。[0..permIndex-1] 为已经生成好的部分。
* @param permIndex
当前排列的位置。
private static void permutation(char[] dict, char[] permutation, int permIndex) {
for (int i = 0; i & dict.length; i++) {
permutation[permIndex] = dict[i];
if (permIndex == permutation.length - 1) {
System.out.println(Arrays.toString(permutation));
// 递归生成 [permIndex+1..permutation.length-1] 部分。
permutation(dict, permutation, permIndex + 1);
private static boolean containsDuplicate(char[] dict) {
Set&Character& duplicateChecker = new HashSet&Character&();
for (char c : dict) {
if (duplicateChecker.contains(c)) {
return true;
duplicateChecker.add(c);
return false;
已有帐号?
无法登录?
社交帐号登录}

我要回帖

更多关于 排列与组合 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信