1 条题解

  • 0
    @ 2024-10-20 20:15:15

    题解:

    因为Monster是懒狗,所以题解也很水。

    首先应该是可以记忆化搜索爆搜的(确信,当然我没试。

    读懂题意可知,每天的情况有两种,被抽查和不被抽查。如果没被查,那么消耗的能量就和昨天一样,也就是不需要额外消耗能量;如果被查,则考虑三种消耗能量的方案中最划算的那种,注意下标处理,由此可得递推公式。

    $$\left \{ \begin{array}{cl} & dp[i] = dp[i - 1] & flag = true\\ & dp[i] = min({dp[i - 1] + x,\ dp[max(i - 7, 0)] + y,\ dp[max(i - 30, 0)] + z}) & flag = false\\ \end{array} \right. \\ flag表示第days[i]天是否被抽查。 $$

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n, x, y, z, last_day=0;
        cin >> n;
        // 使用哈希表存储days
        unordered_set<int> days;
        for (int i = 0; i < n; i++)
        {
            cin >> x;
            days.insert(x);
            // 记录抽查的最后一天作为递推终点
            last_day = max(last_day, x);
        }
        cin >> x >> y >> z;
        vector<int> dp(last_day + 1, 0);
        // 递推转移
        for (int j = 1; j <= last_day; j++)
        {
            if (days.find(j) == days.end())
                dp[j] = dp[j - 1];
            else
                // 注意下标处理
                dp[j] = min({dp[j - 1] + x, dp[max(0, j - 7)] + y, dp[max(0, j - 30)] + z});
        }
        cout << dp[last_day] << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    215
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    (无)
    递交数
    148
    已通过
    16
    上传者