#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>
using namespace std;
bool canJump(const vector<int>&v)
{
int maxDis = 0;
for(int i = 0; i < v.size() - 1; ++i)
{
if(i <= maxDis)
{
maxDis = max(maxDis,v[i] + i);
}
}
return maxDis >= v.size() - 1;
}
int JumpCnt(const vector<int>& v)
{
int cnt = 0, curEnd = 0, curLong = 0;
for(int i = 0; i < v.size() - 1;++i)
{
curLong = max(curLong,i + v[i]);
if(i == curEnd)
{
++cnt;
curEnd = curLong;
}
}
return cnt;
}
bool canJump_q(vector<int>& nums,int st)
{
queue<int>q;
int n = nums.size();
q.push(st);
while(!q.empty())
{
int node = q.front();
q.pop();
if(nums[node] == 0)return true;
if(nums[node] < 0)continue;
if((node + nums[node]) < n)q.push(node + nums[node]);
if((node - nums[node]) > 0)q.push(node - nums[node]);
nums[node] = -nums[node];
}
return false;
}
bool canJump(vector<int>& nums,int st)
{
if(st < 0 || st >= nums.size() || nums[st] < 0)return false;
if(nums[st] == 0) return true;
nums[st] = -nums[st];
return canJump(nums,st+nums[st]) || canJump(nums,st-nums[st]);
}
int dfs(int cur,vector<int>& memo,int d,int n,const vector<int>&arr)
{
if(memo[cur] != -1)return memo[cur];
int res = 1;
for(int i = cur + 1; i <= min(cur + d, n -1) && arr[i] < arr[cur]; ++i)
{
res = max(res, 1+dfs(i,memo,d,n,arr));
}
for(int i = cur - 1; i >= max(cur -d,0) && arr[i] < arr[cur]; --i)
{
res = max(res,1+dfs(i,memo,d,n,arr));
}
memo[cur]=res;
return res;
}
int maxJumps(vector<int>& arr, int d) {
int n = arr.size();
vector<int>memo(n,-1);
int res = 1;
for(int i = 0; i < n; ++i)
{
res = max(res,dfs(i,memo,d, n,arr));
}
return res;
}
int maxScore(const vector<int>&nums,int k)
{
int n = nums.size();
deque<int>dq;
vector<int>dp(n);
dp[0] = nums[0];
dq.push_back(0);
for(int i = 0; i < n - 1; ++i)
{
while(!dq.empty() && (i - dq.front()) >= k)dq.pop_front();
while(!dq.empty() && dp[dq.back()] <= dp[i])dq.pop_back();
dq.push_back(i);
dp[i + 1] = dp[dq.front()] + nums[i+1];
}
return dp[n-1];
}
bool canReach(string s,int minJump,int maxJump)
{
int n = s.size();
vector<int>f(n),pre(n);
f[0] = 1;
for(int i = 0 ; i < minJump; ++i)
{
pre[i] = 1;
}
for(int i = minJump; i < n; ++i)
{
int left = i - maxJump,right = i - minJump;
if(s[i] == '0')
{
int total = pre[right] - (left <= 0 ? 0:pre[left]);
f[i] = (total!=0);
}
pre[i] = pre[i-1]+f[i];
}
return f[n-1];
}
int main()
{
// //LeetCode55
// vector<int>v{2,3,1,1,4};
// cout << canJump(v) << endl;
//LeetCode45
// vector<int>v{2,3,1,1,4};
// cout << JumpCnt(v) << endl;
// //LeetCode1306
// vector<int>nums{4,2,3,0,3,1,2};
// // cout << canJump_q(nums,5) << endl;
// // nums={3,0,2,1,2};
// // cout << canJump_q(nums,2) << endl;
// cout << canJump(nums,5) << endl;
//LeetCode1340
vector<int>nums{6,4,14,6,8,13,9,7,10,6,12};
int d = 2;
cout << maxJumps(nums,d) << endl;
//LeetCode1696
nums = {1,-1,-2,4,-7,3};
int k = 2;
cout << maxScore(nums,k) << endl;
//LeetCode1871
string s = "011010";
int minJump = 2, maxJump = 3;
cout << canReach(s,minJump,maxJump) << endl;
return 0;
}