【问题描述】
【输入形式】
输入的第一行为一个整数 t (1≤ t ≤ 104),表示测试用例的组数。
每个测试用例的第一行为一个整数 n (1≤ n ≤ 2×105),表示数组 a 的元素个数
接下来一行包含 n 个整数 a1、a2、...、an (1 ≤ ai ≤ 109),表示数组 a 的元素
【输出形式】
对于每个测试用例,输出独立一行,表示选择合适的开始位置后经过上述操作可以获得的最大分数。
【样例输入】
4 5 7 3 1 2 3 3 2 1 4 6 2 1000 2 3 995 1 5 1 1 1 1 1
【样例输出】
7 6 1000 5
【判例说明】
20%的测试数据 n≤10000
70%的测试数据 n≤100000
100%的测试数据 n≤200000
完整代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
vector<int> a(n + 1, 0);//使用n+1避免越界,最后一个位置不使用
for (int i = 1; i <= n; i++) cin >> a[i];
vector<int> dp(n + 1, 0);//dp数组用于记录位置i开始可获最大分数
for (int i = n; i >= 1; i--)//从后向前更新
{
//如果可以跳转,则更新dp[i]为当前分数加dp[i + a[i]],如果i + a[i] > n,则加0
if (i + a[i] <= n) dp[i] = a[i] + (i + a[i] > n ? 0 : dp[i + a[i]]);
else dp[i] = a[i];
}
int maxscore = 0;
for (int i = 1; i <= n; i++) maxscore = max(maxscore, dp[i]);
cout << maxscore << endl;
}
return 0;
}