#include using namespace std; const int N = 1e4 + 10; const int INF = 0x3f3f3f3f; int n, m; // n个关卡,每个关卡都有一样的m个通道 int a[N]; // 第i个通道可以让你前进a[i]关,,比如:现在第x关,选择i通道,将到达第x+a[i]关 int b[N]; // 当你离开第s关时,将获得b[s]分的奖励 int f[N]; // 动态规划数组,f[i]表示离开第i关时可以获得的最大分数 int ans = -INF; // 通关时最多能够获得的分数 /* 6 2 2 3 1 0 30 100 30 30 答案:131 6 2 2 3 1 0 30 100 30 -1 答案:101 */ int main() { cin >> n >> m; // 输入n和m // 每一个关卡都有m个通道,a[i]表示第i个通道可以让你前进a[i]关 int mx = 0; for (int i = 1; i <= m; i++) { cin >> a[i]; mx = max(mx, a[i]); } for (int i = 0; i < n; i++) // 关卡是从下标0开始的 cin >> b[i]; // 通关i关时可以获得的奖励分数 // 动态规划 // 状态表示:f[i]表示通关第i关时可以获得的最大分数 // 状态转移:f[i] = max(f[i],f[i-a[j]]+b[i-a[j]]) // 初始化:f[0] = 0 // 答案:f[n] // 因为得分可能是负数,所以初始化的时候,需要将f[i]初始化为-0x3f memset(f, -0x3f, sizeof f); f[0] = 0; for (int i = 1; i < n + mx; i++) { // 遍历每个阶段 // 考虑当前阶段的所有决策,也就是到达这个阶段,可以有哪些决策 // 决策:选择第j个通道,那么到达这个阶段,可以获得的最大分数就是f[i-a[j]]+b[i-a[j]] // 所以,f[i] = max(f[i],f[i-a[j]]+b[i-a[j]]) for (int j = 1; j <= m; j++) { if (i - a[j] >= 0) f[i] = max(f[i], f[i - a[j]] + b[i - a[j]]); } } for (int i = n - 1; i < n + mx; i++) ans = max(ans, f[i] + b[i]); cout << ans << endl; return 0; }