题目描述
给出一个长度为 \(n\) 的序列 \(b\)。设 \(b\) 的一个子序列 \(c\) 的长度为 \(m\),它的第 \(i\) 个元素在原序列的下标为 \(c_i\),要求对于任意的 \(1\le i < m\),有 \(c_{i + 1} - c_i = b_{c_{i + 1}} - b_{c_i}\) 。此时这个子序列的贡献为 \(\sum\limits^{m}_{i = 1}b_{c_i}\)。求所有合法的子序列的贡献中最大的贡献。
数据范围:\(1\le n \le 2\times 10^5\) 。
解法
当我写下这篇文章的时候,世界上所有的人都知道我不会移项了。
由 \(c_{i + 1} - c_i = b_{c_{i + 1}} - b_{c_i}\) 移项得,\(b_{c_{i+1}} - c_{i+1} = b_{c_{i}} - c_{i}\) 也就是值减下标要相等。
然后就变成了一道简单的 DP 题目了。将所有值减下标相等的数加起来即可。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 2e5 + 5;
long long n, a[maxn], f[maxn << 2], ans;
int main() {
cin >> n;
for(int i = 1; i <= n; i ++)
cin >> a[i];
for(int i = 1; i <= n; i ++)
ans = max(ans, f[a[i] - i + n] += a[i]);
cout << ans << endl;
}