题目描述
假设有排成一行的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];
}
}