一只青蛙现在在一个数轴上,它现在要从点 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;
}