栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

算法46-机器人在K步后从M点到达P点问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

算法46-机器人在K步后从M点到达P点问题

题目:

四个参数N表示行走范围,M 表示起点,k表示步数,p表示目标位置,计算出从M 点出发,经过K步之后到达P点有几种方法
机器人在1点和N 点只能向中间走,机器人在除了两端的任意位置都可以自由选择向左或向右走

分析:

题目已经很明确,一共可以分为三种情况

在1点 只能往2 点走,计算出所有方法数

在n点,只能往n-1点走,计算出所有方法数

在任意n点,可以往n+1或n-1 走,计算出两种方案所有方法数,然后相加

代码:

package main

import(
	"fmt"
	// "math"
	// "strconv"
)
//cur==m  当前位置   rest==k剩余几步
func walk(n,cur,rest,p int) int{
	if rest ==0{
		if cur==p{
			return 1
		}
		return 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)

}
// n 范围  m起始位置  k 需要走k步  p目标位置   
func way(n,m,k,p int)int {
	if n<2 || k<1 ||m<1 || m>n || p<1 || p>n{
		return 0
	}
	return walk(n,m,k,p)
}
func main(){
	fmt.Println(way(7,3,2,3))
}

加上缓存:

package main

import(
	"fmt"
	// "math"
	// "strconv"
)
//cur==m  当前位置   rest==k剩余几步
func walk(n,cur,rest,p int,dp [][]int) int{
	if dp[cur][rest]!=-1{
		return dp[cur][rest]
	}
	if rest ==0{
		if cur==p{
			dp[cur][rest]=1
			return dp[cur][rest]
		}
		return 0
	}
	if cur==1{
		
		dp[cur][rest]= walk(n,2,rest-1,p,dp)
		return dp[cur][rest]
	}
	if cur==n{
		
		dp[cur][rest]= walk(n,n-1,rest-1,p,dp)
		return dp[cur][rest]
	}
	
	dp[cur][rest]= walk(n,cur+1,rest-1,p,dp)+walk(n,cur-1,rest-1,p,dp)
	return dp[cur][rest]
}
// n 范围  m起始位置  k 需要走k步  p目标位置   
func way(n,m,k,p int)int {
	if n<2 || k<1 ||m<1 || m>n || p<1 || p>n{
		return 0
	}
	dp:=[][]int{}
	for i:=0;i
		tmp:=[]int{}
		for j:=0;j
			tmp=append(tmp,-1)
		}
		dp=append(dp,tmp)
	}
	return walk(n,m,k,p,dp)
}

func main(){
	fmt.Println(way(70,30,20,30))
}

动态规划:

package main

import(
	"fmt"
	// "math"
	// "strconv"
)
//cur==m  当前位置   rest==k剩余几步
func walk(n,cur,rest,p int,dp [][]int) int{
	if dp[cur][rest]!=-1{
		return dp[cur][rest]
	}
	if rest ==0{
		if cur==p{
			dp[cur][rest]=1
			return dp[cur][rest]
		}
		return 0
	}
	if cur==1{
		
		dp[cur][rest]= walk(n,2,rest-1,p,dp)
		return dp[cur][rest]
	}
	if cur==n{
		
		dp[cur][rest]= walk(n,n-1,rest-1,p,dp)
		return dp[cur][rest]
	}
	
	dp[cur][rest]= walk(n,cur+1,rest-1,p,dp)+walk(n,cur-1,rest-1,p,dp)
	return dp[cur][rest]
}
// n 范围  m起始位置  k 需要走k步  p目标位置   
func way(n,m,k,p int)int {
	if n<2 || k<1 ||m<1 || m>n || p<1 || p>n{
		return 0
	}
	dp:=[][]int{}
	for i:=0;i
		tmp:=[]int{}
		for j:=0;j
			tmp=append(tmp,-1)
		}
		dp=append(dp,tmp)
	}
	return walk(n,m,k,p,dp)
}


func process1(n,m,k,p int) int{
	dp:=[][]int{}
	for i:=0;i
		tmp:=[]int{}
		for j:=0;j
			tmp=append(tmp,0)
		}
		dp=append(dp,tmp)
	}
	// 第一行初始化为0,它的实际值也为0,因此不用再处理
	//第一列只有当cur=p的时候为1,其他也为0   不用处理
	dp[p][0]=1

	for j:=1;j
		dp[1][j]=dp[2][j-1]
	}
	//有数据的依赖关系,每一个格子数据依赖左上和左下位置,所以一列一列来填(按行来填的话拿不到左下位置)
	// 一般情况取左上和左下的和
	//最后一行因为dp初始化的时候多加了一行,这样i+1就不会越界,而且最后一行因为左上有值,左下为0,相加就相当于等于左上,符合规则,因此也不用再处理
	for j:=1;j<=k;j++{
		for i:=1;i<=n;i++{
			dp[i][j]=dp[i-1][j-1]+dp[i+1][j-1]
		}
	}
	for i:=0;i
		fmt.Println(dp[i])
	}
	fmt.Println(dp[m][k])
	return dp[m][k]


}
func main(){
	// fmt.Println(way(7,2,5,3))
	process1(7,2,5,3)

}

总结:
1 由数据的依赖关系,每一个格子数据依赖左上和左下位置,所以一列一列来填(按行来填的话拿不到左下位置)
2 最后一行因为dp初始化的时候多加了一行,这样i+1就不会越界,而且最后一行因为左上有值,左下为0,相加就相当于等于左上,符合规则,因此也不用再处理

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1032943.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号