【拼多多】20250309笔试真题第3题记录

因为之前坐过二维dp(后来才知道这其实叫序列dp)的题,所以看到这个题还是有一些思路的,但是这个题的关键点在于初始化,一定要初始化非法状态,不能一上来就初始化全为0

这题还是有收获的

不过还是那句话,菜就多练

#include <bits/stdc++.h>
using namespace std;

int main(int argc, char const* argv[]) {
    int n = 0, m = 0;
    cin >> n >> m;
    int a[n] = {0};
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    // 在 m 分钟内读完 n 页, 每一分钟最多读 2 页
    if (n > 2 * m) {
        cout << "-1";
        return 0;
    }
    double dp[n + 1][m + 1];
    // dp[i][j]表示第i分钟读了j页能获取到最大知识量
    // 只要在 m 分钟内读完 n 页就可以
    // 最大知识量显然为max({dp[1][n], dp[2][n], dp[3][n], ... dp[m][n]})

    // 关键的初始化
    // dp[i][j] = -1 表示不合法状态, 比如说 1 分钟最多读完第 2 页, 不可能读完第 3 页
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <=n; j++) {
            dp[i][j] = -1.0;
        }
    }
    // 第 0 分钟读完 0 页获得的知识量为 0.0
    dp[0][0] = 0.0;
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            // 注意这里一开始的 i = j = 1
            // 也就是dp[1][1] 表示第 1 分钟读完第 1 页能获得的最大知识量
            // 只读一页且状态合法
            if (dp[i - 1][j - 1] > -1) {
                dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + a[j - 1]);
            }
            // 读 2 页且状态合法
            else if (j > 1 && dp[i - 1][j - 2] > -1) {
                dp[i][j] = max(dp[i][j], dp[i - 1][j - 2] + (a[j - 1] + a[j - 2]) / 2);
            }
        }
    }

    double ans = 0.0;
    for (int i = 1; i <= m; i++) {
        ans = max(ans, dp[i][n]);
    }
    cout << fixed << setprecision(1) << ans;

    system("pause");
    return 0;
}

全部评论

相关推荐

评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务