Boredom
首先可以发现一个性质,如果要选一个数,就一定是全部选完,因为选择第二个的时候不会再删掉数字了,所以只会使得答案变得更优,但如果不删就只会使得答案变得更劣。
我们定义: d p [ i ] dp[i] dp[i] 为最大值限制为 i i i 的所有数字进行操作,所能得到的最大值。那么对于 d p [ i ] dp[i] dp[i] 来说,我们要么一开始直接选完 i i i ,要么使得它被其他数字删除。
那么先考虑第一种情况:我们要选择 i i i ,那么首先肯定可以获得 c n t [ i ] × i cnt[i]×i cnt[i]×i 的分数,而后 i − 1 i-1 i−1 必然被删除,所以剩余的极大值就是 d p [ i − 2 ] dp[i-2] dp[i−2] ,所以此情况的最大值就是 c n t [ i ] × i + d p [ i − 2 ] cnt[i]×i+dp[i-2] cnt[i]×i+dp[i−2]
第二种情况:使得其被删除,那么考虑 d p [ i − 1 ] dp[i-1] dp[i−1] (只有其可以删除 i i i ),如果其最大值是用了 i − 1 i-1 i−1 所得到的,那么自然答案自然为 d p [ i − 1 ] dp[i-1] dp[i−1] ,让若不是,那么我们也可以 d p [ i − 1 ] dp[i-1] dp[i−1] 和第一种情况取 m a x max max ,必定可以得到正解。
综上, d p [ i ] = m a x ( c n t [ i ] × i + d p [ i − 2 ] , d p [ i − 1 ] ) ( i ≥ 2 ) dp[i]=max(cnt[i]×i+dp[i-2],dp[i-1])(i≥2) dp[i]=max(cnt[i]×i+dp[i−2],dp[i−1])(i≥2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int n;
ll cnt[N], a[N], dp[N];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
cnt[a[i]]++;
}
dp[1] = cnt[1];
for (ll i = 2; i <= 100000; ++i) {
dp[i] = max(i * cnt[i] + dp[i - 2], dp[i - 1]);
}
printf("%lld", dp[100000]);
}