ACM 训练日志记录 · 思考 · 成长 提交 / 修改记录
王梓豪 / 题目列表训练档案
导出

P1052 [NOIP 2005 提高组] 过河

来源:洛谷 ★ 1500

DP自评已掌握
本题活力0.43按难度、完成结果与训练证据估算

算法如山行则将至

题目描述

青蛙需从0跳至L,每次跳S到T步,求最少踩石子数。

代码

#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;
}