算法如山行则将至
题目描述
青蛙需从0跳至L,每次跳S到T步,求最少踩石子数。
思考与重做
王梓豪的同题记录 · 1 条
- 王梓豪 · 2026-09-14本次记录最后更新 2026.9.14
完成结果:提示后完成自评已掌握
这题长度比较长,不能采用简单的dp,但是可以通过压缩空白路径的方式减小到10000左右的长度。
需要留意的是s=t的时候需要特判,因为此时只能走s的倍数,而s!=t时存在gcd(s,t)==1,可以保证任何位置都可以走到,非常牛逼
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int l, s, t, m, temp;
cin >> l;
cin >> s >> t >> m;
vector<int> v(m);
for (int i = 0; i < m; i++)
{
cin >> v[i];
}
sort(v.begin(),v.end());
if (s == t)
{
int ans = 0;
for (int i = 0; i < m; i++)
{
if (v[i] % s == 0)
{
ans++;
}
}
cout << ans << '\n';
return 0;
}
vector<int> a(11000, 0);
int last = 0;
int now = 0;
for (int i = 0; i < m; i++)
{
now += min(v[i] - last, 100);
a[now] = 1;
last = v[i];
}
l = now + min(l - last, 100);
const int INF = 1e9;
vector<int> dp(l + t + 1, INF);
dp[0] = 0;
for (int i = 1; i <= l + t; i++)
{
for (int j = i - t; j <= i - s; j++)
{
if (j >= 0)
{
dp[i] = min(dp[i], dp[j] + a[i]);
}
}
}
int ans = INF;
for (int i = l; i <= l + t; i++)
{
ans = min(ans, dp[i]);
}
cout << ans << '\n';
return 0;
}