// 演算法 / Algorithm: 與 C 版相同。dp[i] 表示可達；用滑動視窗計數 pre 維護
// 前驅區間 [i-maxJump, i-minJump] 內的可達數量，單趟 O(n) 掃描。
// Same as the C version. dp[i] = reachable; a sliding-window count `pre` keeps
// the number of reachable predecessors in [i-maxJump, i-minJump] in one O(n) pass.
#include <string>
#include <vector>
using namespace std;

class Solution {
public:
    bool canReach(string s, int minJump, int maxJump) {
        int n = s.size();                    // 字串長度 / length of the string
        if (s[n - 1] == '1') return false;   // 末端非 '0' 直接不可達 / last cell must be '0'

        // vector<bool> 是可變長陣列；這裡長度 n，全部初始化為 false
        // vector<bool> is a resizable array; size n, every element starts false
        vector<bool> dp(n, false);
        dp[0] = true;                        // 起點可達 / the start is reachable
        int pre = 0;                         // 視窗內可達前驅個數 / reachable predecessors in window

        for (int i = 1; i < n; ++i) {        // 逐一判斷每個下標 / evaluate each index
            // 右端新增 dp[i-minJump] / right edge gains dp[i-minJump]
            if (i >= minJump && dp[i - minJump]) ++pre;
            // 左端移除 dp[i-maxJump-1] / left edge drops dp[i-maxJump-1]
            if (i > maxJump && dp[i - maxJump - 1]) --pre;
            // 落點為 '0' 且視窗內有可達前驅 → 本格可達
            // Landing cell is '0' and window has a reachable predecessor → reachable
            if (s[i] == '0' && pre > 0) dp[i] = true;
        }

        return dp[n - 1];                    // 回傳末端是否可達 / return whether the last cell is reachable
    }
};
