59 lines
1.9 KiB
C++
59 lines
1.9 KiB
C++
#include <bits/stdc++.h>
|
||
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;
|
||
} |