#华为笔试#9.14笔试第1题

public class Exer1Preview {
    /*
        题目:有一个人过桥,桥上面有 n 块木板,有些木板是断的,如果
        走到了断的木板上,则会损失一条生命值,这个人的初始生命值条数
        是 m 条生命。每次可以选择 不跳(从当前位置走到下一块木板),
                               或跳一格(从当前位置跳过一块木板),
                               或跳两格(从当前位置跳过两块木板)
        要求走到终点时,生命值至少有1条。
        求顺利过桥的方案数?
        输入:m —— 代表初始生命值条数
             n —— 代表桥的长度,即桥上总共有多少块木板
             k —— 代表桥上有多少块木板是断裂的
             k个整数,分别代表断裂木板的编号,第一块木板的编号是 1
        输出:顺利过桥的方案数
     */
    public static void main(String[] args) {

        // 处理输入
        Scanner scanner = new Scanner(System.in);
        int mOfLifes = scanner.nextInt();
        int nOfBridges = scanner.nextInt();
        int kOfBreakages = scanner.nextInt();
        // 起点对应的位置是 0 ,终点对应的位置是 nOfBridges + 1
        boolean[] sequenceOfBridges = new boolean[nOfBridges + 2];
        int sequence = 0;  // 代表断裂木板的编号
        for(int i = 0;i < kOfBreakages;i++){
            sequence = scanner.nextInt();
            // 若第 i 块木板断裂,则 sequenceOfBridges[i]为true,否则为false
            sequenceOfBridges[sequence] = true;
        }

        // 中间过程
        /*
            算法思想:
                动态规划,dp[i][j]:从起点走到第i块木板剩余j条命的 走法方案数
                初始状态:
                    dp[0][mOfLifes] = 1, (从起点走到起点,剩余mOfLifes条命的走法只有1种)
                    dp[0][j] = 0 ,其中j < mOfLifes (从起点走到起点,剩余j条命的走法是0种)
                状态转移方程:
                    dp[i][j+lose] = dp[i-1][j] + dp[i-2][j] + dp[i-3][j]
                分析:若第i块木板断裂,则lose的值为-1,若第i块木板未断裂,则lose的值为0
                若想求出从起点走到第i块木板有多少种走法,取决于:
                    从起点走到第i-1块木板的走法,再走一步
                    从起点走到第i-2块木板的走法,再跳过一格
                    从起点走到第i-3块木板的走法,再跳过两格
                因为第i块木板有可能是断裂的,所以走到第i块时,剩下的生命值是j+lose
         */
        int[][] dp = new int[nOfBridges+2][mOfLifes+1];
        dp[0][mOfLifes] = 1;
        int lose = 0;
        for(int i = 1;i <= nOfBridges+1;i++){
            lose = sequenceOfBridges[i] ? -1 : 0;
            // 走一步
            if(i-1 >= 0){
                for(int j = 1;j <= mOfLifes;j++){
                    dp[i][j+lose] = dp[i][j+lose] + dp[i-1][j];
                }
            }

            // 跳一格
            if(i-2 >= 0){
                for(int j = 1;j <= mOfLifes;j++){
                    dp[i][j+lose] = dp[i][j+lose] + dp[i-1][j];
                }
            }

            // 跳两格
            if(i-3 >= 0){
                for(int j = 1;j <= mOfLifes;j++){
                    dp[i][j+lose] = dp[i][j+lose] + dp[i-1][j];
                }
            }
        }

        // 处理输出
        int solutions = 0;
        for(int i = 1;i < mOfLifes;i++){
            solutions = solutions + dp[nOfBridges+1][i];
        }
        System.out.println(solutions);
    }
}

#华为笔试#
全部评论

相关推荐

群星之怒:不是哥们,你就不好奇瘫痪三十年的老植物人是啥样的吗?
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务