是个有趣的问题。 话说回来,jmdhb的苹果为什么一模一样呢?
这显然不重要。 重点是将这个问题抽象化的方法。
从m个苹果中,取出n个苹果,问几个可能性,这显然是典型的组合问题
如果把m个苹果分成n个等分。 显然只有一个可能性。
把苹果分成n堆,求可能性,我马上想不出数学模型。 很自然地,我想到了迭代近似和递归的数学方法。
追加主题进行说明,1、3、1和1、1、3是相同的划分方法。 那个分发可能等价于递增或递增排列苹果。
于是我们开始递归计数:
递归操作:遍历M~0,如果m小于数组中的上一个元素,则表示这是递减时的最大可能性,为新元素分配m,对其馀元素执行递归操作。
递归结束条件:数组的最后一位也完成赋值。 剩下的要素不超过前几个。
递归退出操作:将计数器加1。 如果需要,可以输出此时的数组。
实现c算法(值得自己练习制作细节)。
#include'stdafx.h '
#包含
intCount=0;
用户名称空间;
voidprintarr(intdishnum,int*arr ) )
for(inti=0; I
for(intj=0; Jj
出局了
出局了
}
出局了
}
voidallocation(intapplenumleft,intdishNum,intidx,int*arr ) }
if(idx==(dishnum-1 ) ) }
if(ARR[idx-1]=applenumleft ) {
arr[idx]=appleNumLeft;
出局;
printarr(dishnum,arr );
返回;
}
else
返回;
}
else{
for(intj=applenumleft; j=0; j---- ) {
if(idx==0) {
arr[idx]=j;
allocation(applenumleft-j,dishNum,idx 1,arr );
}
else{
if(ARR[idx-1]=j ) {
arr[idx]=j;
allocation(applenumleft-j,dishNum,idx 1,arr );
}
}
}
}
}
int_tmain(intargc,_TCHAR*argv[] () ) ) ) ) ) ) ) ) )。
{
intM,n;
cinMN;
int*a=newint[N];
分配(m,n,0,a );
出局了
delete[]a;
a=NULL;
返回0;
}
验证算法是否正确。
递归地,每个级别都会缩短递归函数中的一个循环。 直到最后。 如果最小值不存在,则返回而不递增计数器。
然后是用python誊写算法。 清册要点:
python没有传递引用,而是具有全局列表。
for循环是迭代器。
全局列表必须初始化。
由于可以直接打印列表,因此省略了一个打印函数。 (因此,没有打印applet_t ) )。
因为没有使用面向对象,所以感觉很奇怪。 应该做苹果分配器类。
#-* -编码: utf-8-*
efallocate(m,n,idx ) :
全球,计数
ifidx==N-1:
ifa[idx-1]=M:
a[idx]=M
计数=1
打印机
返回
else:
返回
else:
foriinreversed (范围(0,M 1) ) :
ifidx==0:
a[idx]=i
分配(m-I、n、idx 1) )。
else:
ifa[idx-1]=i:
a[idx]=i
分配(m-I、n、idx 1) )。
if__name__=='__main__':
m,N=raw_input ('请输入苹果数量和盘子数量,用空格分隔(n ) ) () ).strip ).split ) )。
a=[]
foriinrange(0,int ) n ) :
a.append(0) )。
计数=0
(allocate(int(m )、int (n )、0 ) ) ) ) ) ) ) ) )
打印计数
两个代码在视觉上的简洁差别很明显。 python天生就容易阅读,书写也不错(缩进比大括号容易输入多了。 在中,代码缩短了近一半,对ROP可能不友好: p (ROP=resumeorientedprogramming )。