一只青蛙现在在一个数轴上,它现在要从点 11 跳到点 nn ,它每次可以向右跳不超过 dd 个单位。比如,它可以从点 xx 跳到点 x+ax+a ( 1<=a<=d )(1<=a<=d) 。特别的,青蛙只能在有百合花的点上停留。保证点 11 和点 nn 之间有一些点有百合花。请输出青蛙到达点 nn 的最小跳跃次数。

输入输出格式
输入格式
输入的第一行包括两个正整数 nn 和 dd ( 2<=n<=100, 1<=d<=n-1 )(2<=n<=100,1<=d<=n−1) 。 输入的第二行是一个长度为 nn 的无空格字符串,由0和1组成,表示哪些点上有百合花(1表示有)。保证点 11 和点 nn 有百合花。

输出格式
输出青蛙的最小跳跃次数。如果它不可能到达,输出-1。

单调队列优化: O(n)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <deque>
using namespace std;
const int maxn = 1e5 + 5;
char str[maxn];
int dp[maxn];
int main() {
	int n, d;
	cin >> n >> d;
	cin >> str + 1;
	if (str[1] == '0' || str[n] == '0') {
		cout << "-1" << endl;
		return 0;
	} 
	memset(dp, 64, sizeof(dp));
	dp[0] = dp[1] = 0;
	deque<int> q;
	q.push_back(1);
	int ins = 0;
	for (int i = 2; i <= n; i++) {
		if (str[i] == '1') {
			while (!q.empty() && q.front() < i - d) {
				q.pop_front();
			}	
			if (q.empty()) {
				ins = 1;break;
			}
			dp[i] = dp[q.front()] + 1;
			while (!q.empty() && dp[q.back()] > dp[i]) {
				q.pop_back();
			}
			q.push_back(i);
		}
	}
	if (ins) {
		cout << "-1" << endl;
	} else {
		cout << dp[n] << endl;
	}
	return 0;
}