首页 > 试题广场 >

袋鼠过河

[编程题]袋鼠过河
  • 热度指数:33743 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子,每隔一米就有一个,每个桩子上都有一个弹簧,袋鼠跳到弹簧上就可以跳的更远。每个弹簧力量不同,用一个数字代表它的力量,如果弹簧力量为5,就代表袋鼠下一跳最多能够跳5米,如果为0,就会陷进去无法继续跳跃。河流一共N米宽,袋鼠初始位置就在第一个弹簧上面,要跳到最后一个弹簧之后就算过河了,给定每个弹簧的力量,求袋鼠最少需要多少跳能够到达对岸。如果无法到达输出-1

输入描述:
输入分两行,第一行是数组长度N (1 ≤ N ≤ 10000),第二行是每一项的值,用空格分隔。


输出描述:
输出最少的跳数,无法到达输出-1
示例1

输入

5
2 0 1 1 1

输出

4
while True:
    try:
        n=int(input().strip())
        num_list=list(map(int,input().split(' ')))
        #print(num_list)
        dp=[]
        infinit=float('inf')
        dp=[infinit for i in range(n+1)]
        #print(dp)
        dp[0]=0
        for i in range(1,n+1):
            for j in range(i):
                if num_list[j]+j>=i:#运用动态规划,如果num_list[j]+j>=i表示可以调到i处
                    dp[i]=min(dp[i],dp[j]+1)#因此需要与dp[i]处的原值进行比较,dp[j]+1表示dp[j]处的值再跳一次
        if dp[n-1]!=infinit:
            print(dp[n])
        else:
            print(-1)
    except:
        break
发表于 2019-06-11 21:01:40 回复(0)
# 动态规划,最简单的一道题了。需要记录当前最短步长即可
def jump(a, n):
    path = {0:0}
    # position, num_steps 
    for start, step in enumerate(a):
        if start in path:
            for j in range(1, step+1):
                end = min(start+j, n)
                if end not in path:
                    path[end] = path[start] + 1
                else:
                    path[end] = min(path[start] + 1 , path[end])

    print(-1 if n not in path else path[n])

while True:
    try:
        n = int(input())
        a = list(map(int, input().split()))
        jump(a, n)
    except:
        break

编辑于 2018-10-05 20:36:12 回复(0)
inf=float('inf')
a,b=int(input()),list(map(int,input().split()))
N=10000
dp=[inf for i in range(N+1)]
dp[0]=0
for i in range(1,a+1):
    for j in range(i):
        if b[j]+j>=i:
            dp[i]=min(dp[i],dp[j]+1)
print(-1 if dp[a]==inf else dp[a])

发表于 2018-10-02 14:39:58 回复(0)
def jump(l):
    ans = []
    l_reverse = l[::-1]
    for i, value in enumerate(l_reverse):
        if i == 0:
            ans.append(1)
        else:
            if value == 0:
                ans.append(100001)
            elif value > i: 
# 如果某个位置已经可以跳过对岸,该位置步数为1  (囧,题目说跳到最后一个木桩算过,开始以为一定要跳到最后一个木桩,实际只要跳过对岸即可。)
                ans.append(1)
            else:
                ans.append(min(ans[i - value:i]) + 1)
    return ans

if __name__ == '__main__':
    N = input()
    l = [int(i) for i in input().split(' ')]
    ans = jump(l)
    if ans[-1] > 10000:
        print(-1)
    else:
        print(ans[-1])


'''
动态规划,从后往前计算该位置跳过对岸所需最少步数
'''

编辑于 2018-09-02 11:31:59 回复(0)
if __name__ == '__main__':
    n = int(input())
    J = list(map(int, input().split(" ")))
    dp = [9999] * (n + 1)
    dp[0] = 0
    for i in range(n):
        dp[i:i + J[i] + 1] = [min(j, dp[i] + 1) for j in dp[i:i + J[i] + 1]]
    if dp[-1] != 9999:
        print(dp[-1])
    else:
        print(-1)

典型动态规划问题。

发表于 2018-08-11 13:25:42 回复(0)
N = int(input())
listN = list(map(int, input().split()))
listN.append(1)
def jump(listN):
    step = 0
    for i in range(len(listN),0,-1):
        for j in range(i):
            if listN[j]>=len(listN)-j-1:
                step += 1
                listN=listN[:j+1]
                break
        if len(listN)==1:
            return step
    return -1
print(jump(listN))
发表于 2018-07-25 21:48:06 回复(0)
N=int(input())
num=list(map(int,input().split()))
mindp=[0,]#第一个桩的最小跳一定是0次
for i in range(1,N+1):#初始化每个桩的最小跳次数
    mindp.append(10001)
for i in range(1,N+1):#依次计算跳到每个桩需要的最小跳次数
    for j in range(1,i+1):#遍历前面所有的桩,找到一个可以跳到当前桩的位置
        if num[i-j]==0:#如果弹力为零,则当前树桩无用,继续下一个
            continue
        if (i-j)+num[i-j]>=i:
            mindp[i]=min(mindp[i],mindp[i-j]+1)
if mindp[N]==10001:#统计完所有树桩的最小跳次数后,输出结果
    print(-1)
else:
    print(mindp[N])

发表于 2018-05-30 13:53:46 回复(0)

常规DP,注意题目的坑,要越过最后一个柱子,所以注意一下:

```
import sys
N = int(input())
list_x = [int(x) for x in input().split()]
ans = [0 for i in range(N+1)]
ans[0] = 1 
for i in range(1,N+1): 
    if i!=N: #处理最后一步的特殊情况  
        if list_x[i]==0: 
            continue
    temp_ans = [] 
    for j in range(i): 
        if ans[j]==0: 
            continue 
        if list_x[j]+j>=i:
            temp_ans.append(ans[j]+1)
    if len(temp_ans)!=0:
        ans[i] = min(temp_ans) 
print(ans[-1]-1)

```

编辑于 2018-05-22 16:21:15 回复(0)
def short_path(spring):     distance=len(spring)     if distance==0:         return 0     if spring[0]<1:         return -1     if distance<=1:         return 1     else:         res_list=[]         for i in range(distance):             if distance-i<=spring[i]:                 res = short_path(spring[:i])                 if res >= 0:                     res_list.append(res+1)         return min(res_list) if res_list else -1 def veryshort_path(t_list):     L = len(t_list)     if t_list[0]<=0:         return -1     else:                  res=[0] + [L+1]*L         for i in range(L):                              for j in range(i):                 if t_list[j]>=i-j and res[j]+1<res[i]:                     res[i]=res[j]+1                          if t_list[i]>=len(t_list)-i:                 res[-1] = res[i]+1                 return res[-1] if res[-1] <= L else -1         return res[-1] if res[-1] <= L else -1 # spring = [2,0,1,1,1,1,2] putin1=input('') putin2=input('') spring = [int(x) for x in putin2.split(' ')] # print(spring) print(veryshort_path(spring))

发表于 2018-04-24 22:53:43 回复(1)

python solution:

这道题把leetcode上的jump game I和jump game II结合起来了。解法如下,时间复杂度为O(n)

def canJump(A):
    jump=[0]
    for i in range(1,a):
        jump.append(max(jump[-1],A[i-1])-1)
        if jump[-1]<0:
            return False
    return True

a,b=int(input()),list(map(int,input().split()))

jump,curEnd,curFurthest=0,0,0
for i in range(a):
    curFurthest=max(curFurthest,i+b[i])
    if curEnd==i:
        jump+=1
        curEnd=curFurthest
print(jump if canJump(b) else -1)
发表于 2017-10-26 16:33:47 回复(3)
n = int(input())
nums = list(map(int, input().split()))
dp = [0xfffffff]*n
for i in range(n-1, -1, -1):
    for j in range(1, nums[i]+1):
        dp[i] = min(dp[i], dp[i+j]+1 if i+j<n else 1)
print(dp[0] if dp[0]<0xfffffff else -1)

发表于 2017-10-06 21:46:08 回复(0)
if __name__ == '__main__':
    N = int(input())
    nums = [int(x) for x in input().split()]

    inf = float('inf')
    dp = [inf for j in range(N+1)]  # 跳到第i个木桩需要的最少次数
    dp[0] = 0  # 第0个木桩需要跳0次
    for i in range(N):
        j = 1
        # 跳 j 步会跳到i+j,需要跳dp[i]+1次,不要跳出去
        while j <= nums[i] and i+j <= N:
            dp[i+j] = min(dp[i+j], dp[i]+1)
            j += 1
    print(dp[N] if dp[N] < inf else -1)
编辑于 2017-10-06 11:44:22 回复(0)
dp = [0]*100005
v =[0]*100005

def toriver(listr,n):
    tanhuang = [int(x) for x in listr.split(' ')]
    dp[0] = 0
    v[0] = 1
    for i in range(tanhuang[0]+1):
        dp[i] = 1
        v[i] = 1
    
    for i in range(1,int(n)):
        if tanhuang[i] == 0:
            continue
        for j in range(1,tanhuang[i]+i+1):
            if (v[i] == 1 and v[j]!=1):
                dp[j] = dp[i] + 1
                v[j] = 1
    if v[int(n)] != 0:
        return dp[int(n)]
    else:
        return -1
    

while True:
    try:
        n = input()
        listr = input()
        endt = toriver(listr,n)
        print (endt)
    except EOFError:
        break

Python 参考了别人的思路,主要是动归的思想,希望对用Python的人有帮助
发表于 2017-09-26 00:21:46 回复(0)