程序员代码面试指南刷题--第四章.机器人达到指定位置方法数

题目描述
假设有排成一行的N个位置,记为1~N,开始时机器人在M位置,机器人可以往左或者往右走,如果机器人在1位置,那么下一步机器人只能走到2位置,如果机器人在N位置,那么下一步机器人只能走到N-1位置。规定机器人只能走k步,最终能来到P位置的方法有多少种。由于方案数可能比较大,所以答案需要对1e9+7取模。
输入描述:

输出包括一行四个正整数N(2<=N<=5000)、M(1<=M<=N)、K(1<=K<=5000)、P(1<=P<=N)。

输出描述:

输出一个整数,代表最终走到P的方法数对109+710^9+7109+7取模后的值。

示例1

输入

5 2 3 3

输出

3

解法一:暴力递归

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] info = br.readLine().trim().split(" ");
        int n = Integer.parseInt(info[0]);
        int m = Integer.parseInt(info[1]);
        int k = Integer.parseInt(info[2]);
        int p = Integer.parseInt(info[3]);
        int res = findPathNum(n,m,k,p);
        System.out.println(res);
    }
    public static int findPathNum(int n,int m,int k,int p){
        if(n<2||m<1||m>n||p<1||p>n) return 0;
        return walk(n,m,k,p);
    }
    public static int walk(int n,int m,int k,int p){
        if(k==0){
            return m==p?1:0;
        }
        if(m==1){
            return walk(n,m+1,k-1,p);
        }
        if(m==n){
            return walk(n,m-1,k-1,p);
        }
        return (walk(n,m-1,k-1,p)%1000000007+walk(n,m+1,k-1,p)%1000000007)%1000000007;
    }
}

解法二:动态规划

思路: 暴力递归改动态规划模板

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] info = br.readLine().trim().split(" ");
        int n = Integer.parseInt(info[0]);
        int m = Integer.parseInt(info[1]);
        int k = Integer.parseInt(info[2]);
        int p = Integer.parseInt(info[3]);
        int res = findPathNum(n,m,k,p);
        System.out.println(res);
    }
    public static int findPathNum(int n,int m,int k,int p){
        if(n<2||m<1||m>n||p<1||p>n) return 0;
        int[][] dp = new int[k+1][n+1];
        dp[0][p] = 1;
        for(int i=1;i<k+1;i++){
            for(int j=1;j<n+1;j++){
                if(j==1){
                    dp[i][j] = dp[i-1][2];`在这里插入代码片`
                }else if(j==n){
                    dp[i][j] = dp[i-1][n-1];
                }else{
                    dp[i][j] = (dp[i-1][j-1]+dp[i-1][j+1])%1000000007;
                }
            }
        }
        return dp[k][m];
    }
}

解法二:动态规划(压缩空间)

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] info = br.readLine().trim().split(" ");
        int n = Integer.parseInt(info[0]);
        int m = Integer.parseInt(info[1]);
        int k = Integer.parseInt(info[2]);
        int p = Integer.parseInt(info[3]);
        int res = findPathNum(n,m,k,p);
        System.out.println(res);
    }
    public static int findPathNum(int n,int m,int k,int p){
        if(n<2||m<1||m>n||p<1||p>n) return 0;
        int[] dp = new int[n+1];
        dp[p] = 1;
        for(int i=1;i<k+1;i++){
            int left = dp[1];
            for(int j=1;j<n+1;j++){
                int tmp = dp[j];
                if(j==1){
                    dp[j] = dp[2];
                }else if(j==n){
                    dp[j] = left;
                }else{
                    dp[j] = (left+dp[j+1])%1000000007;
                }
                left = tmp;                
            }
        }
        return dp[m];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值