【Java/算法/组合】楼梯共有12级台阶,每步可上1级,也可上2级,要用8步走完这12级台阶,问共有多少种不同的走法?并请列举出这些走法

【数学解法】

此题貌似与组合无关,分析后可发现是直接相关的。

设走一级n次,走二级m次,那么有:

n+m=8

n+2m=12

解这个二元一次方程得n=4,m=4.

至此可言,只能走4次二级,4次一级登上这层楼梯。

求不同得走法,就是在8步中,选4次2级(其余全为1级)。

8选4即C84=8*7*6*5/4*3*2*1=2*35=70次

【程序解法】

思路:做一个数组{0,1,2,3,4,5,6,7}进行8选4,选出4个元素作为下标,把数组{"1","1","1","1","1","1","1","1"}中得对应项置为2,此即走法。

比如说,{0,1,2,3,4,5,6,7}进行8选4后得到[0,1,2,3],那么{"1","1","1","1","1","1","1","1"}将变成{"2","2","2","2","1","1","1","1"},这就是这一步对应的走法。

Footstep类:

复制代码
package test230426;

import java.util.List;

import test230425.Combination;

/**
 * 楼梯共有12级台阶,每步可上1级,也可上2级,要用8步走完这12级台阶,问共有多少种不同的走法?并请列举出这些走法
 */
public class Footstep {
    public static void main(String[] args) {
        final int[] arr= {0,1,2,3,4,5,6,7};
        Combination c=new Combination(arr,4);
        List<List<Integer>> results=c.getResults();
        
        int idx=0;
        for(List<Integer> res:results) {
            String[] steps= {"1","1","1","1","1","1","1","1"};
            
            for(int i:res) {
                steps[i]="2";
            }
            
            String str=String.join(",", steps);
            
            System.out.println(String.format("%02d", ++idx) +"."+str);
        }
    }
}
复制代码

Combination类:

复制代码
package test230425;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 数学中排列组合中的组合器实现
 * 
 */
public class Combination {
    /**
     * 用于存放中间结果
     */
    private Stack<Integer> stack;
    
    /**
     * 用于存放结果
     */
    private List<List<Integer>> results;
    
    /**
     * 构造函数
     * @param arr 进行组合的元素
     * @param count 选多少个
     */
    public Combination(int[] arr,int count) {
        if(count>arr.length) {
            throw new ArrayIndexOutOfBoundsException(count+">"+arr.length);
        }
        
        stack = new Stack<>();
        results=new ArrayList<>();
        doSelect(arr,count,0,0);
    }
    
    /**
     * 进行选择
     * @param arr 目标数组
     * @param expect 期望选择数量
     * @param actual 实际选择数量
     * @param current 当前下标
     */
    private void doSelect(int[] arr, int expect, int actual, int current) {
        if(actual == expect) {
            List<Integer> list=new ArrayList<>();
            
            for(int i:stack) {
                list.add(i);
            }
            
            results.add(list);
            
            return;
        }
         
        for(int i=current;i<arr.length;i++) {
            if(!stack.contains(arr[i])) {
                stack.add(arr[i]);
                doSelect(arr, expect, actual+1, i);
                stack.pop();
            }
        }
    }
    
    /**
     * 取得组合结果
     * @return
     */
    public List<List<Integer>> getResults(){
        return results;
    }
    
    /**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        final int[] arr= {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30};
        final int count=2;
        
        Combination c=new Combination(arr,count);
        List<List<Integer>> results=c.getResults();
        
        int idx=0;
        for(List<Integer> res:results) {
            System.out.println(String.format("%02d", ++idx) +"."+res);
        }
    }
}
复制代码

【输出】

复制代码
01.2,2,2,2,1,1,1,1
02.2,2,2,1,2,1,1,1
03.2,2,2,1,1,2,1,1
04.2,2,2,1,1,1,2,1
05.2,2,2,1,1,1,1,2
06.2,2,1,2,2,1,1,1
07.2,2,1,2,1,2,1,1
08.2,2,1,2,1,1,2,1
09.2,2,1,2,1,1,1,2
10.2,2,1,1,2,2,1,1
11.2,2,1,1,2,1,2,1
12.2,2,1,1,2,1,1,2
13.2,2,1,1,1,2,2,1
14.2,2,1,1,1,2,1,2
15.2,2,1,1,1,1,2,2
16.2,1,2,2,2,1,1,1
17.2,1,2,2,1,2,1,1
18.2,1,2,2,1,1,2,1
19.2,1,2,2,1,1,1,2
20.2,1,2,1,2,2,1,1
21.2,1,2,1,2,1,2,1
22.2,1,2,1,2,1,1,2
23.2,1,2,1,1,2,2,1
24.2,1,2,1,1,2,1,2
25.2,1,2,1,1,1,2,2
26.2,1,1,2,2,2,1,1
27.2,1,1,2,2,1,2,1
28.2,1,1,2,2,1,1,2
29.2,1,1,2,1,2,2,1
30.2,1,1,2,1,2,1,2
31.2,1,1,2,1,1,2,2
32.2,1,1,1,2,2,2,1
33.2,1,1,1,2,2,1,2
34.2,1,1,1,2,1,2,2
35.2,1,1,1,1,2,2,2
36.1,2,2,2,2,1,1,1
37.1,2,2,2,1,2,1,1
38.1,2,2,2,1,1,2,1
39.1,2,2,2,1,1,1,2
40.1,2,2,1,2,2,1,1
41.1,2,2,1,2,1,2,1
42.1,2,2,1,2,1,1,2
43.1,2,2,1,1,2,2,1
44.1,2,2,1,1,2,1,2
45.1,2,2,1,1,1,2,2
46.1,2,1,2,2,2,1,1
47.1,2,1,2,2,1,2,1
48.1,2,1,2,2,1,1,2
49.1,2,1,2,1,2,2,1
50.1,2,1,2,1,2,1,2
51.1,2,1,2,1,1,2,2
52.1,2,1,1,2,2,2,1
53.1,2,1,1,2,2,1,2
54.1,2,1,1,2,1,2,2
55.1,2,1,1,1,2,2,2
56.1,1,2,2,2,2,1,1
57.1,1,2,2,2,1,2,1
58.1,1,2,2,2,1,1,2
59.1,1,2,2,1,2,2,1
60.1,1,2,2,1,2,1,2
61.1,1,2,2,1,1,2,2
62.1,1,2,1,2,2,2,1
63.1,1,2,1,2,2,1,2
64.1,1,2,1,2,1,2,2
65.1,1,2,1,1,2,2,2
66.1,1,1,2,2,2,2,1
67.1,1,1,2,2,2,1,2
68.1,1,1,2,2,1,2,2
69.1,1,1,2,1,2,2,2
70.1,1,1,1,2,2,2,2
复制代码

END

posted @   逆火狂飙  阅读(217)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2022-04-26 运行期建立HikariDataSource和JdbcTemplate
2018-04-26 【js】用正则表达式对文字进行局部替换
2018-04-26 【python】用正则表达式进行文字局部替换
2018-04-26 [Python] 错误“IndentationError: unindent does not match any outer indentation level”是什么意思?
2018-04-26 【Tip】如何在chrome浏览器中查看网页的Header
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示