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
题意:给你n个正整数,每个正整数不会超过100000,你每次可以选择一个在数组中存在的数字k,然后删掉这个数字,并且顺带删掉数组中所有的k+1和k-1,同时获得k点积分,问如何获得尽可能多的积分
思路,因为最大的数不会超过100000,所以可以设dp[i]为删掉了所有大于等于i的数字能获得的最多积分,那么有
dp[i] = max(dp[i+1], dp[i+2]+sum[i]*i),其中sum[i]为第i个数字在数组中出现的次数
#include<stdio.h>
#include<algorithm>
using namespace std;
#define LL long long
int sum[100005];
LL dp[100005];
int main(void)
{
int n, i, x;
scanf("%d", &n);
for(i=1;i<=n;i++)
{
scanf("%d", &x);
sum[x]++;
}
for(i=100000;i>=1;i--)
dp[i] = max(dp[i+1], dp[i+2]+(LL)sum[i]*i);
printf("%lld\n", dp[1]);
return 0;
}