题目链接:http://codeforces.com/problemset/problem/455/A
题意:有n个数,每一次你可以选择ak,并且把所有ak - 1 和 ak + 1 删掉,得到分数ak , 问你可以得到的最大的得分是多少。所有数的范围都不超过10^5。
思路:f[i]表示操作数的范围在1~i时的最大得分。如果打算选数i,那么i-1肯定不能选;不选i,则可以选i-1。
f[i] = max( f[i-1] , f[i-2] + num[i] * i ) num[i]表示数i出现的次数。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)
#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod 100000007
const int maxn = 100009;
LL f[maxn];
int num[maxn];
int n,temp;
int main()
{
int uplim = 0;
Clean(f,0);
Clean(num,0);
cin>>n;
rep(i,1,n)
{
scanf("%d",&temp);
uplim = max( uplim , temp );
num[temp]++;
}
f[1] = num[1];
rep(i,2,uplim)
{
f[i] = max( f[i-1] , f[i-2] + (LL)num[i]*i );
}
printf("%I64d\n",f[uplim]);
return 0;
}