问题描述:
上阶梯,一次可以上一阶或者二阶,共N阶台阶。求共有多少种方法上去?并列举出来。
如果仅仅是求取上去方法数量的结果可以这样:
<?php
$n = 4;
echo foo($n);
function foo($n){
if(is_int($n) && $n > 0){
if($n == 1) return 1;
if($n == 2) return 2;
return foo($n - 1) + foo($n - 2);
}
return 0;
}
如果需要列举出每一种方法
<?php
//问题规模
$n = 7;
$res = getResult($n);
echo "问题规模",$n,",共有",count($res),"种组合<br>";
echo implode("<br>",$res );
//获取结果集
function getResult($n){
//组合数组
$result = [];
for($i = 0 ; $i <= floor($n/2); $i++){
$j = $n - 2 * $i;
$s = ($i == 0||$j==0)? 1 : C($i+$j,$i);
$temArr = [];
for($x = 0;$x < $s;$x++){
$printArr = getRound($i,$j,$temArr);
$temArr[] = $printArr;
$str = str_repeat("1",$i+$j);
foreach($printArr as $v){ //组建组合
$str = substr_replace($str,"2",$v,1);
}
$result[] = $str;
}
}
return $result;
}
//获取一种组合
function getRound($m,$n,$disarr = array()){
$s = ($m == 0||$n==0)? 1 : C($m+$n,$m);
if($m == 0 || count($disarr) >= $s) return array();
$arr = range(0,$m + $n - 1);
if($m == 1) return array(array_rand($arr,$m));
$ar = array_rand($arr,$m);
if(in_array($ar,$disarr)) return getRound($m,$n,$disarr);
return $ar;
}
//求阶乘
function F($n){
return array_product(range(1, $n));
}
//求排列
function A($n, $m){
return F($n)/F($n-$m);
}
//求组合
function C($n, $m){
return A($n, $m)/F($m);
}