解題報告:
思路:可以像01揹包那樣考慮,定義dp[i]爲處理1到 i 數字得到的最大收益,分爲拿和不拿。拿的話i - 1就不能拿 dp[i] = cnt[i] * i + dp[i-2],不拿的話i-1可以拿dp[i] = dp[i-1]。轉移方程:dp[i] = max(dp[i-1], cnt[i]*i + dp[i-2])。
代碼:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e5 + 10;
ll cnt[N];
ll dp[N];
ll n;
void solve(ll maxn){
dp[1] = cnt[1];
dp[2] = max(cnt[2] * 2, dp[1]);
for(ll i=3; i<=maxn; ++i){
dp[i] = max(dp[i-1], cnt[i] * i + dp[i-2]);
}
printf("%lld\n", dp[maxn]);
memset(cnt, 0, sizeof(cnt));
}
int main(){
while(~scanf("%lld", &n)){
ll maxn = 0;
for(ll i=0; i<n; ++i){
ll x;
scanf("%lld", &x);
maxn = max(maxn, x);
cnt[x]++;
}
solve(maxn);
}
return 0;
}