不是这样,速度可以往上加,即使两块石头相隔很远,速度足够大也能跳过去。那个链接的Ilikemac回帖已基本给出正确答案了。
现在给出dfs和dp的解,可能有bug,没做深度测试。- #include <vector>
- #include <iostream>
- using namespace std;
- //basically we can use a dfs to solve the problem
- bool jumpDfs(vector<bool> & 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<int> & stone_idx, int init_speed) {
- //convert stone stone_position to a bool array {1,1,1,0,0,1,1,0,0,0,0,0,1}
- int n=stone_idx.back()+1;
- vector<bool> stone_pos(n);
- for(int p:stone_idx) stone_pos[p]=true;
- return jumpDfs(stone_pos,0,init_speed);
- }
- //dfs has a lot repeated calculation, we can use dp to avoid it
- //assume init_speed >= 0
- bool canJumpOverDp(vector<int> & stone_idx, int init_speed) {
- //convert stone stone_position to a bool array {1,1,1,0,0,1,1,0,0,0,0,0,1}
- int n=stone_idx.back()+1;
- vector<bool> 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<vector<bool>> dp(n, vector<bool>(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; p<n; ++p) {
- if(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<int> 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;
- }
复制代码 |