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 ak) and delete it, at that all elements equal to ak + 1 and ak - 1 also must be deleted from the sequence. That step brings ak points to the player.
Alex is a perfectionist, so he decided to get as many points as possible. Help him.
The first line contains integer n (1 ≤ n ≤ 105) that shows how many numbers are in Alex's sequence.
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 105).
Print a single integer — the maximum number of points that Alex can earn.
2
1 2
2
3
1 2 3
4
9
1 2 1 3 2 2 2 2 3
10
Consider the third test example. At first step we need to choose any element equal to 2. After that step our sequence looks like this [2, 2, 2, 2]. Then we do 4 steps, on each step we choose any element equals to 2. In total we earn 10 points.
题意就是 从一个序列中删除一个数K 同时删除K-1,K+1 此时能够得到K分不 求最后能得到的最多的分数
主要的是一个dp的思路 就是首先 读取序列的时候保存出现过的数字的个数p[i] 删除它能得到的分数就是p[i]*i
因为同时删除相邻的两个数 所以就从小的数开始算起 dp[0]=0 dp[1]=p[1]
计算到i时的分数 如果是删除了i-1 则dp[i]=dp[i-1] 如果是删除了i-2 则dp[i]=dp[i-2]+p[i]*i;
取大值就可以了
代码如下。。。dp还是硬伤
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#define eps 1e-8
#define op operator
#define MOD 10009
#define MAXN 100010
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FOV(i,a,b) for(int i=a;i>=b;i--)
#define REP(i,a,b) for(int i=a;i<b;i++)
#define REV(i,a,b) for(int i=a-1;i>=b;i--)
#define MEM(a,x) memset(a,x,sizeof a)
#define ll __int64
using namespace std;
struct node
{
int num;
int cnt;
int sum;
bool operator<(const node& x)const
{
return sum>x.sum;
}
};
node no[MAXN];
int a[MAXN];
int b[MAXN];
int main()
{
//freopen("ceshi.txt","r",stdin);
int n;
while(scanf("%d",&n)!=EOF)
{
MEM(b,0);
int temp;
for(int i=0;i<MAXN;i++)
no[i].cnt=0;
int c=0;
for(int i=0;i<n;i++)
{
scanf("%d",&temp);
no[temp].num=temp;
no[temp].cnt++;
if(no[temp].cnt==1) c++;
}
for(int i=1;i<MAXN;i++)
{
no[i].sum=no[i].cnt*i-no[i-1].cnt*(i-1)-no[i+1].cnt*(i+1);
}
sort(no,no+MAXN);
ll s=0;
for(int i=0;i<MAXN;i++)
{
if(no[i].sum>0)
{
s+=no[i].num*no[i].cnt;
}
no[no[i].num-2].sum+=(no[no[i].num-1].num*no[no[i].num-1].cnt);
}
printf("%I64d\n",s);
// for(int i=0;i<n;i++)
// cout<<no[i].num<<endl;
}
return 0;
}