1148. 过河
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度)。坐标为0的点表示桥的起点,坐标为L的点表示桥的终点。青蛙从桥的起点开始,不停的向终点方向跳跃。一次跳跃的距离是S到T之间的任意正整数(包括S,T)。当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥。
题目给出独木桥的长度L,青蛙跳跃的距离范围S,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。
Input
输入的第一行有一个正整数L(1 <= L <= 109),表示独木桥的长度。第二行有三个正整数S,T,M,分别表示青蛙一次跳跃的最小距离,最大距离,及桥上石子的个数,其中1 <= S <= T <= 10,1 <= M <= 100。第三行有M个不同的正整数分别表示这M个石子在数轴上的位置(数据保证桥的起点和终点处没有石子)。所有相邻的整数之间用一个空格隔开。
Output
输出只包括一个整数,表示青蛙过河最少需要踩到的石子数。
Sample Input
102 3 52 3 5 6 7
Sample Output
2
// Problem#: 1148
// Submission#: 3237242
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <string.h>
#include <vector>
#include <iomanip>
#include <map>
#include <stack>
#include <functional>
#include <list>
#include <cmath>
using namespace std;
const int MAX = 10050;
int main() {
std::ios::sync_with_stdio(false);
while (1) {
int L;
int dp[MAX];
int stone[MAX];
int stonePos[105];
int s, t, m;
cin >> L >> s >> t >> m;
if (cin.eof()) break;
stonePos[0] = 0;
for (int i = 1; i <= m; i++) cin >> stonePos[i];
sort(stonePos + 1, stonePos + m + 1);
if (s == t) { // 由于后面有状态压缩,所以这里要进行特殊情况的处理
int ans = 0;
for (int i = 1; i <= m; i++) {
if (stonePos[i] % s == 0) ans++;
}
cout << ans << endl;
continue;
}
for (int i = 1; i <= m; i++) { // 状态压缩,如果两个石头的距离大于90,就设为90
if (stonePos[i] - stonePos[i - 1] > 90) {
int moveDistance = stonePos[i] - (stonePos[i - 1] + 90);
for (int j = i; j <= m; j++) stonePos[j] -= moveDistance;
}
}
for (int i = 0; i < MAX; i++) stone[i] = 0;
for (int i = 1; i <= m; i++) stone[stonePos[i]] = 1;
for (int i = 1; i < MAX; i++) dp[i] = -1;
dp[0] = 0;
L = stonePos[m] + 90;
for (int i = 0; i < L; i++) {
if (dp[i] == -1) continue;
for (int j = i + s; j <= i + t; j++) {
if (dp[j] == -1 || dp[i] + stone[j] < dp[j]) dp[j] = dp[i] + stone[j];
}
}
int ans = MAX;
for (int i = L; i < L + t; i++) if (ans > dp[i] && dp[i] != -1) ans = dp[i];
cout << ans << endl;
}
//getchar();
//getchar();
return 0;
}