【拼多多】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; }