暴力递归到动态规划(记忆搜索)

假设有排成一行的N个位置,记为1~N,N一定大于或等于2
开始时,机器人在其中的M位置上(M一定是1~N中的一个)
如果机器人来到1位置,那么下一步只能往右来到2位置
如果机器人来到N位置,那么下一步只能往左来到N-1位置
如果机器人来到中间位置,那么下一步可以往左也可以往右
规定机器人必须走K步,最终能来到P位置的方法有多少种?
给定4个参数N,M,K,P,返回方法数。
暴力方法

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class RobotWalk{
	public static int ways1(int N,int M,int K,int P){
        //参数无效直接返回0
        if(N < 2 || K < 1 || M < 1 || M > N || P < 1 || P < N){
            return 0;
        }
        //总共N个位置,从M点出发,还剩下K步,返回最终能到达P的方法数
        return walk(N,M,K,P);
    }
    //N 位置为1-N,固定参数
    //cur 当前在cur位置,可变参数
    //rest,还剩下res步没有走,可变参数
    //p,最终目标是P,固定参数
    public static int walk(int N,int cur,int rest,int P){
        if(rest == 0){
            return cur == P ? 1 : 0;
        }

        if(cur == 1){
            return walk(N, 2, rest - 1, P);
        }
        if(cur == N){
            return walk(N, N - 1, rest - 1, P);
        }

        return walk(N, cur + 1, rest - 1, P) + walk(N, cur - 1, rest - 1, P);
    }
 
}

但是暴力递归会重复搜索,增加一个缓存机制,把每次搜索的数据记录下来,这样就成为了动态规划。
在这里插入图片描述
在这里插入图片描述

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class RobotWalk{
	public static int waysCache(int N,int M,int K,int P){
        //参数无效直接返回0
        if(N < 2 || K < 1 || M < 1 || M > N || P < 1 || P < N){
            return 0;
        }
        //总共N个位置,从M点出发,还剩下K步,返回最终能到达P的方法数

        int[][] dp = new int[N + 1][ K + 1];
        for(int row = 0; row <= N; row++){//行
            for(int col = 0; col <= K; col++){
                dp[row][col] = -1;
            }
        }
        return walkCache(N,M,K,P,dp);
    }
    //N 位置为1-N,固定参数
    //cur 当前在cur位置,可变参数
    //rest,还剩下res步没有走,可变参数
    //p,最终目标是P,固定参数
    public static int walkCache(int N,int cur,int rest,int P,int[][] dp){
        if(dp[cur][rest] != -1){
            return dp[cur][rest];
        }

        if(rest == 0){
            dp[cur][rest] = cur == P ? 1 : 0; 
            return dp[cur][rest];
        }

        if(cur == 1){
            dp[cur][rest] = walkCache(N, 2, rest - 1, P,dp);
            return dp[cur][rest];
        }
        if(cur == N){
            dp[cur][rest] = walkCache(N, N - 1, rest - 1, P, dp);
            return walkCache(N, N - 1, rest - 1, P,dp);
        }
        dp[cur][rest] = walkCache(N, cur + 1, rest - 1, P,dp) + walkCache(N, cur - 1, rest - 1, P,dp);
        return dp[cur][rest];
    }
 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值