Boredom
Alex doesn’t like boredom. That’s why whenever he gets bored, he comes up with games. One long winter evening he came up with a game and decided to play it.
Given a sequence a consisting of n integers. The player can make several steps. In a single step he can choose an element of the sequence (let’s denote it a k) and delete it, at that all elements equal to a k + 1 and a k - 1 also must be deleted from the sequence. That step brings a k points to the player.
Alex is a perfectionist, so he decided to get as many points as possible. Help him.
题目大意:给你一个长度为n的序列 a,你每次能取序列里面的一个数 a[i](得到a[i]分数),并且序列里面 a[i]-1 和 a[i]+1 的个数都要减一(如果个数为0,那就不减),问最后能得到的最大分数;
首先要明白,一个数 a[i] 要取,一定是把这个序列的所有 a[i] 都取掉,要不就不取 a[i] ;
现在要判断的就是存不存在 a[i] 和 a[i]-1 或者 a[i]+1 一起取?
不存在,可以发现如果:
- a[i] 的个数比 a[i]-1 大,取了 a[i],a[i]-1 的个数就没有了;
- a[i] 的个数比 a[i]-1 小,取了 a[i],a[i]-1 的个数有,但是之前在计算 a[i]-1 时如果取了a[i]-1,那么 a[i] 的个数就没有了;
- a[i] 的个数和 a[i]-1 一样,那和第一种情况一样;
所以如果 a[i] 取,那么 a[i]-1 就一定不能取,状态要从 a[i]-2 转化过来;
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100100;
const int M=2000100;
const LL mod=1e9+7;
int a[N],sum[N],mx;
LL dp[N],ans;
int main(){
int n;cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[a[i]]++;
mx=max(mx,a[i]);
}
ans=dp[1]=sum[1];
for(int i=2;i<=mx;i++){
dp[i]=max(dp[i-1],dp[i-2]+(LL)i*(LL)sum[i]);
ans=max(dp[i],ans);
}
cout<<ans<<endl;
return 0;
}