这道题我在snapchat onsite的时候也遇到了,以前没见过,当时只给出了dfs的解。
现在给出dfs和dp的解,可能有bug,没做深度测试。
#include
#include
using namespace std;
//basically we can use a dfs to solve the problem
bool jumpDfs(vector & stone_pos, int pos, int speed) {
int n=stone_pos.size();
if(pos==n-1) return true;
if(!stone_pos[pos] || pos>=n || speed<1) return false;
for(int s=speed-1; s<=speed+1; ++s) {
if(jumpDfs(stone_pos,pos+s,s)) return true;
}
return false;
}
//assume init_speed >= 0
bool canJumpOverDfs(vector & stone_idx, int init_speed) {
//convert stone_idx to a bool array {1,1,1,0,0,1,1,0,0,0,0,0,1}
int n=stone_idx.back()+1;
vector stone_pos(n);
for(int p:stone_idx) stone_pos[p]=true;
return jumpDfs(stone_pos,0,init_speed);
}
//dfs has a lot of repeated calculations, we can use dp to avoid it
//assume init_speed >= 0
bool canJumpOverDp(vector & stone_idx, int init_speed) {
//convert stone_idx to a bool array {1,1,1,0,0,1,1,0,0,0,0,0,1}
int n=stone_idx.back()+1;
vector stone_pos(n);
for(int p:stone_idx) stone_pos[p]=true;
//assume every stone_position is a stone, the max speed at the end is
less than
int safe_max_speed=init_speed+n-1;
//the actual max speed could be calculated by:
//(init_speed+1) + (init_speed+2) + ... + max_speed = n;
// max_speed < safe_max_speed
//dp[p][s] means at stone position p, if there exists a case that frog
has speed s
vector> dp(n, vector(safe_max_speed+1));
if(init_speed>=1) dp[0][init_speed-1]=true;
dp[0][init_speed]=dp[0][init_speed+1]=true;
for(int p=1; pif(stone_pos[p]) {
for(int s=1; s<=safe_max_speed; ++s) {
//any dp[p][s] can be achived by the previous stone_position
p-(s-1) with speed s-1
//after the jump, increase speed by 1, then we get stone_
position p with speed s;
//also it can be achived by the previous stone_position p-s
with speed s;
//and the previous stone_position p-(s+1) with speed s+1
if(p>=s-1) dp[p][s]=dp[p-s+1][s-1];
if(p>=s) dp[p][s]=dp[p][s] || dp[p-s][s];
if(p>=s+1) dp[p][s]=dp[p][s] || dp[p-s-1][s+1];
}
}
}
//check the last stone_position, if there exists a case that frog has
any speed
for(bool b:dp[n-1]) {
if(b) return true;
}
return false;
}
int main() {
vector stone_idx={0,1,2,5,6,12};
//initial speed 5,6,7 are good to reach the end
cout << "Dfs: init speed=4, can jump over? " << canJumpOverDfs(stone_idx
,4) << endl;
cout << "Dp: init speed=4, can jump over? " << canJumpOverDp(stone_idx,
4) << endl;
cout << "Dfs: init speed=5, can jump over? " << canJumpOverDfs(stone_idx
,5) << endl;
cout << "Dp: init speed=5, can jump over? " << canJumpOverDp(stone_idx,
5) << endl;
}