重发:一个用动态规划的题目

cmckliao5 2008-07-10 02:09:30
在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度)。坐标为0的点表示桥的起点,坐标为L的点表示桥的终点。青蛙从桥的起点开始,不停的向终点方向跳跃。一次跳跃的距离是S到T之间的任意正整数(包括S,T)。当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥。
题目给出独木桥的长度L,青蛙跳跃的距离范围S,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。
【输入文件】
输入文件river.in的第一行有一个正整数L(1 <= L <= 1000000000),表示独木桥的长度。第二行有三个正整数S,T,M,分别表示青蛙一次跳跃的最小距离,最大距离,及桥上石子的个数,其中1 <= S <= T <= 10,1 <= M <= 100。第三行有M个不同的正整数分别表示这M个石子在数轴上的位置(数据保证桥的起点和终点处没有石子)。所有相邻的整数之间用一个空格隔开。
【输出文件】
输出文件river.out只包括一个整数,表示青蛙过河最少需要踩到的石子数。
时间限制1秒。


我的思路是,如果两个石头间的距离d>S*T,则缩短为d=(d mod (S*T))+1。觉得这是个很模糊的一个未经验证的想法,不过还是过了大半的数据。不知道这样想对不对。
...全文
114 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
tailzhou 2008-07-10
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 tailzhou 的回复:]
“我的思路是,如果两个石头间的距离d>S*T,则缩短为d=(d mod (S*T))+1。觉得这是个很模糊的一个未经验证的想法,不过还是过了大半的数据。不知道这样想对不对。”

不一定对;若s,t互质,那么是正确的;
若s,t不互质,那么由于S*T...S*T+T之间有些位置是不可能跳到的,所以结果就可能是错误的;
[/Quote]

我想错了,他这里是s-t之间的所有数;
我给看成只有s跟t两个数了;

由于是s-t之间的所有数;
1)若s=t,那么必定可以到达d-d%s点;
2)若s<t,那么s与s+1必定互质,那么必定可以到达d-d % (s*(s+1))与d之间的任何点;
cmckliao3 2008-07-10
  • 打赏
  • 举报
回复
我是想方设法压缩相邻两石头间的路径长度。
cmckliao3 2008-07-10
  • 打赏
  • 举报
回复
换个思路:
如果两石头间距离d>s*t,则d缩短为(d mod(s*t))+t,因为有可能在前t个位置中的任何一个起跳。
然后用一个数组a[]记录情况,a[i]=0则无石头,a[i]=1则有石头,a[]的长度可以优化到((s*t)+t)*m
动态规划:F[i]=min{ f[i-k]+a[i] (其中s<=k<=t且i-k>=s) }
不知道这样行不。
Marffin 2008-07-10
  • 打赏
  • 举报
回复
我不知道我理解对了题意没有,但是看起来如果石子不是连续的铺满了一个T-S+1的区间的话青蛙总是有机会不跳到石子上去的。因为石子的数量(0<M<=100)远小于桥的长度(0<L<=1000000000),分析石子的分布会更有效。
tailzhou 2008-07-10
  • 打赏
  • 举报
回复
dp数组的长度应该取t+1;

用L-t到L的数据初始化数组dp;其中位置L-t对应与数组中的索引0;

假设当前已经计算到了位置i,其对应在数组中的索引为j,那么
dp[j]=min(dp[k])+c 0<=k<=t k!=j;

下一步计算位置i-1,那么其对应在数组中的索引为j+1,若j+1>t,那么j=0;






tailzhou 2008-07-10
  • 打赏
  • 举报
回复
“我的思路是,如果两个石头间的距离d>S*T,则缩短为d=(d mod (S*T))+1。觉得这是个很模糊的一个未经验证的想法,不过还是过了大半的数据。不知道这样想对不对。”

不一定对;若s,t互质,那么是正确的;
若s,t不互质,那么由于S*T...S*T+T之间有些位置是不可能跳到的,所以结果就可能是错误的;
tailzhou 2008-07-10
  • 打赏
  • 举报
回复
由于你这里的 正整数L(1 <= L <= 1000000000)相当大;

而dp[i]只跟dp[i+1...i+t]有关;
所以dp数组的长度取T就可以了;

用一个变量表示当前位置在数组中的索引;数组是一个循环数组,即数组最后一个索引的元素的下一个位置是数组的开头;



tailzhou 2008-07-10
  • 打赏
  • 举报
回复
有点问题,忘了最小跳跃距离了;

dp[i]=min(dp[j])+c i <j <=i+t;
应该是
dp[i]=min(dp[j])+c i+s <=j <=i+t;
tailzhou 2008-07-10
  • 打赏
  • 举报
回复
设dp[i]表示青蛙从桥上的位置i为起点,跳出独木桥最少需要踩到的石子数;
那么
dp[l]=0;
对于任意的0<i<=t 若L-i位置有石子,那么dp[L-i] = 1,否则 dp[L-i] = 0;

对于任意的i<L-t,
有递推式:
dp[i]=min(dp[j])+c i<j<=i+t;
其中若i位置有石子,则c=1,否则c=0;

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧