题目:
a,b两个数之间,用>号和=号表示关系,共有三种可能:a>b a=b b>a。
a,b,c三个数之间,用>号和=号表示关系,共有13种可能:
a=b=c a=b>c c>a=b a=c>b b>a=c a>b=c
b=c>a a>b>c a>c>b b>a>c b>c>a c>a>b
c>b>a
问,n个数,有多少种不同的可能?只要数值,不要输出具体的方案。
求解思路:
假想要把数字放到盒子中,盒子的编号依次为1、2、3、4、....,
放入的规则为:相等的数字放到一个盒子,不相等的数字放到不
同的盒子中,假如最后一个盒子的编号为m,则前面m-1个盒子都不能为空。
例如:
a=b=c 对应于: 盒子1内存放a,b,c
b>a=c 对应于: 盒子1内存放b,盒子2内存放a,c
c>a>b 对应于:盒子1内存放c,盒子2内存放a,盒子3内存放b,
则上述问题变为:把数字放到盒子中有多少种不同的方案。
假设已经有k个数字被装进了盒子,则这k个数字最少占用1个盒
子(都放在一个盒子中),最多占用k个盒子(每个盒子放一个数)。
用数组元素count[i]表示用i个盒子存放数据时的不同方案的个数。
例如:count数组的初始值
表示总共2个数,放在1个盒子中共有1种方案,放在2个盒子中共有2种方案。
总共3种方案。经过一次迭代后,变为:
表示总共3个数,放在1个盒子中共有1种方案,放在2个盒子中共有6种方案,放在3个盒子中共有6种方案。总共13种方案。
再经过一次迭代后,变为:
表示总共4个数,放在1个盒子中共有1种方案,放在2个盒子中共有14种方案,放在3个盒子中共有36种方案,放在4个盒子中共有24种方案。总共75种方案。
再进行迭代,可以继续得出5个数字、6个数字,....时的方案数。
那么,上面的数组中数据是怎么计算出来的呢?
以向存在的三个数加入第4个数为例,在加入第4个数时,可能把第4个数放在已经存在的某个盒子中,也可能把第4个数放在新增加的盒子中。
对于已将3个数字装入1个盒子的方案,
如果不增加盒子数量,则方案数仍然是1。由于此时盒子数是1,方案数1应累计到数组的第1个位置。
如果增加1个盒子,新增加的盒子可能放在现有盒子的左侧,也可能放在右侧,共有两种可能,方案数是2。由于此时盒子数是2,方案数2应累计到数组的第2个位置。
对于已将3个数字装入2个盒子的方案,
如果不增加盒子数量,则方案数是6*2。为什么是6*2呢,因为每个方案在增加数字后变为2个方案,原来有6个方案。由于此时盒子数是2,方案数12应累计到数组的第2个位置。
如果增加1个盒子,新增加的盒子可能有3个插入位置,共有3种可能,方案数是6*3。为什么是6*3呢,因为每个方案在增加数字后变为3个方案,原来有6个方案。由于此时盒子数是3,方案数18应累计到数组的第3个位置。
对于已将3个数字装入3个盒子的方案,
如果不增加盒子数量,则方案数是6*3。为什么是6*3呢,因为每个方案在增加数字后变为3个方案,原来有6个方案。由于此时盒子数是3,方案数18应累计到数组的第3个位置。
如果增加1个盒子,新增加的盒子可能有4个插入位置,共有4种可能,方案数是6*4。为什么是6*4呢,因为每个方案在增加数字后变为4个方案,原来有6个方案。由于此时盒子数是4,方案数24应累计到数组的第4个位置。
最后给出一个程序代码,供参考。
#include "stdio.h"
void main()
{
int i,j,count2[1000],count[1000]={0};
int sum=0,n;
count[1]=1;
count[2]=2;
printf("please input number n (n>3):");
scanf("%d",&n);
for(i=3;i<=n;i++)
{
for(j=2;j<=i;j++)
count2[j]=(count[j]+count[j-1])*j;
for(j=2;j<=i;j++)
count[j]=count2[j];
}
for(i=1;i<=n;i++)
sum+=count[i];
printf("the sum is:%d\n",sum);
}