ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

机器人到达指定位置方法数

2021-10-07 23:30:00  阅读:156  来源: 互联网

标签:cache return cur int 机器人 到达 指定 rest ans


假设有排成一行的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的方法数对取模后的值。

示例1
输入

5 2 3 3

输出

3

说明
1).2->1,1->2,2->3

2).2->3,3->2,2->3

3).2->3,3->4,4->3
示例2

输入

1000 1 1000 1

输出

591137401

说明
注意答案要取模

################################################################################

解题思路一:暴力递归

	public static int ways1(int N,int M,int K,int P) {
		if(N<2||K<1)return 0;
		return walk1(N,M,K,P);
	}
	public static int walk1(int N,int cur,int rest,int P) {//rest:剩余的步数  cur:当前的位置
		if(rest==0)return cur==P?1:0;
		if(cur==1) {
			return walk1(N,cur+1,rest-1,P);
		}
		if(cur==N) {
			return walk1(N,cur-1,rest-1,P);
		}
		return (walk1(N,cur-1,rest-1,P)+walk1(N,cur+1,rest-1,P))%1000000007;
	}

在这里插入图片描述

暴力递归改动态规划的目的只有一个:以空间换取时间,因为暴力递归细分会出现好多重复的暴力展开,浪费了时间,暴力递归改动态规划就是将已经暴力展开的子情况的值记录下来,下次再次遇到相同的子情况就不用再次浪费时间去做暴力展开了,直接用值就行了。

解题思路二:暴力递归改动态规划 1

借助傻缓存cache(哈希表实现),记忆化搜索



	public static int ways2(int N,int M,int K,int P) {
		if(N<2||K<1)return 0;
		HashMap<String,Integer>cache=new HashMap<>();
		return walk2(N,M,K,P,cache);
	}
	public static int walk2(int N,int cur,int rest,int P,HashMap<String,Integer>cache) {//rest:剩余的步数  cur:当前的位置
		String key=String.valueOf(cur)+"_"+String.valueOf(rest);
		if(cache.containsKey(key))return cache.get(key);
		int ans=0;
		if(rest==0) {
			ans=cur==P?1:0;
			cache.put(key, ans);
			return ans;
		}
		
		if(cur==1) {
			ans=walk2(N,cur+1,rest-1,P,cache);
			cache.put(key, ans);
			return ans;
		}
		if(cur==N) {
			ans=walk2(N,cur-1,rest-1,P,cache);
			cache.put(key, ans);
			return ans;
		}
		ans=(walk2(N,cur-1,rest-1,P,cache)+walk2(N,cur+1,rest-1,P,cache))%1000000007;
		cache.put(key, ans);
		return ans;
	}
	

在这里插入图片描述
解题思路三:暴力递归改动态规划 2
哈希表虽然操作都是O(1),但是常数时间还是比较大的,可以采用二维数组的方法来记录。


	public static int ways3(int N,int M,int K,int P) {
		if(N<2||K<1)return 0;
		int[][] cache=new int[N+1][K+1];
		//将数组初始化为-1,表示还没求过这个值
		for(int i=1;i<cache.length;++i) {
			for(int j=0;j<cache[0].length;++j) {
				cache[i][j]=-1;
			}
		}
		return walk3(N,M,K,P,cache);
	}
	public static int walk3(int N,int cur,int rest,int P,int[][] cache) {//rest:剩余的步数  cur:当前的位置
		if(cache[cur][rest]!=-1)return cache[cur][rest];
		int ans=0;
		if(rest==0) {
			ans= cur==P?1:0;
			cache[cur][rest]=ans;
			return ans;
		}
		if(cur==1) {
			ans=walk3(N,cur+1,rest-1,P,cache);
			cache[cur][rest]=ans;
			return ans;
		}
		if(cur==N) {
			ans=walk3(N,cur-1,rest-1,P,cache);
			cache[cur][rest]=ans;
			return ans;
		}
		ans=(walk3(N,cur-1,rest-1,P,cache)+walk3(N,cur+1,rest-1,P,cache))%1000000007;
		cache[cur][rest]=ans;
		return ans;
	}

在这里插入图片描述
解题思路四:暴力递归改动态规划 3
可变的参数K和M,填下面的表
N=7,M=2,K=5,P=3

先确定初始条件,第一列的第M行为1,其他为0
任何列的第一行都只依靠其左下角的值
任何列的最后一行都只依靠其左上角的值
其他位置同时依靠其左上角和左下角的值

在这里插入图片描述

结果就是[M][K]的值


	public static int waysDP(int N,int start,int K,int end) {
		if(N<2||start<1||end>N||K<1||start>N||end<1)return 0;
		int[][] dp=new int[N+1][K+1];
		dp[end][0]=1;
		for(int col=1;col<=K;++col) {
			dp[1][col]=dp[2][col-1];
			dp[N][col]=dp[N-1][col-1];
			for(int row=2;row<N;++row) {
				dp[row][col]=(dp[row-1][col-1]+dp[row+1][col-1]) % 1000000007;
			}
		}
		return dp[start][K];
	}


在这里插入图片描述

标签:cache,return,cur,int,机器人,到达,指定,rest,ans
来源: https://blog.csdn.net/qq_43536978/article/details/120641117

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有