LeetCode #403 Frog Jump

Problem Description

  • A frog is crossing a river. The river is divided into x units and at each unit there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water.
  • Given a list of stones’ positions (in units) in sorted ascending order, determine if the frog is able to cross the river by landing on the last stone. Initially, the frog is on the first stone and assume the first jump must be 1 unit.
  • If the frog’s last jump was k units, then its next jump must be either k - 1, k, or k + 1 units. Note that the frog can only jump in the forward direction.
  • Note:
  • The number of stones is ≥ 2 and is < 1,100.
  • Each stone’s position will be a non-negative integer < 2^31.
  • The first stone’s position is always 0.

Some Details

  • 1100块石头最远可以走到多远呢XD

Solution

    这题的一个关键在于走了i步之后下一格最多i+1个长度单位,因此2^31这个条件没意义。
    那么解决方案就可以从不同方向DP了。
    (1)枚举石子可走长度。开hash记不同位置的石子,可以记录在每个石子可以选择走的长度集合(去重)。O(n^2)
    (2)枚举后续石子下标。记录i号石子可以走的长度,枚举i,j,看看i能不能到达j。O(n^2)
    第二种可以做下剪枝,如果最远也到不了j那后面也不用看了。
    显然(2)的写法优美一点,提出(1)是因为我开始的做法是(1)..
    下面贴的是(2)的代码,(1)的相关问题可以留言交流。

Code

bool g[1110][1110];
int mx[1110];
const int af[3]={-1,0,1};
class Solution {
public:
    bool canCross(vector<int> stones) 
    {
        int n=stones.size(),len=n;
        if (n % 2==0) len=len/2 *(n-1); else len=len*((n-1)/2);
        if (stones[1]!=1) return false;
        if (n==2) return true;
        if (stones[n-1]>len) return false;
        memset(g,0,sizeof(g));
        memset(mx,0,sizeof(mx));
        g[1][1]=true; mx[1]=1;
        for (int i=1;i<n;i++)
        {
            for (int j=i+1;j<n;j++)
            {
                if (stones[j]-stones[i]>mx[i]+1) break;
                for (int k=0;k<3;k++)
                {
                    int T=stones[j]-stones[i]-af[k];
                    if (g[i][T] && !g[j][T+af[k]])
                    {
                        if (j==n-1) return true;
                        g[j][T+af[k]]=true;
                        mx[j]=max(mx[j],T+af[k]);
                    }
                }
            }
        }
        return false;
    }
}; 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值