题目
样例输入1
2
1 2
样例输出1
2
样例输入2
3
1 2 3
样例输出2
4
样例输入3
9
1 2 1 3 2 2 2 2 3
样例输出3
10
思路
预处理:
首先统计每一个x与其数量,声明结构体point,记录 x 与 sum。
按照 x 的大小对结构体数字进行排序。
状态:a[ i ] 表示在到第 i 个 x 时(i 从 1 开始),所得到的最大分数。
初始化:a[ 0 ] = 0
转移过程:如果 p[ i - 1].x == p[ i ].x - 1 (即两个x数值是相邻的),a[ i ] = max(a[ i - 1], a[ i - 2] + p[ i ].x * p[ i ].sum);否则, a[ i ] = a[ i - 1] + p[ i ].x * p[ i ].sum
输出答案:a[ n ],n 为不同 x 的个数
代码
#include<algorithm>
#include<cstring>
using namespace std;
long long is[100010];
long long a[100010];
struct point
{
int x;
int sum;
bool operator<(const struct point &c)const
{
return x < c.x;
}
point(int x = 0, int sum = 0)
{
this->x = x;
this->sum = sum;
}
}p[100010];
int main()
{
int n;
cin >> n;
memset(is, 0, sizeof 0);
int b;
int cnt = 1;
for (int i = 0; i < n; i++)
{
cin >> b;
if (is[b] == 0)
{
p[cnt].x = b;
p[cnt].sum++;
is[b] = cnt;
cnt++;
}
else
p[is[b]].sum++;
}
int nn = cnt - 1;
if (nn == 1)
a[1] = p[1].x * p[1].sum;
else
{
sort(p + 1, p + nn + 1);
a[0] = 0;
a[1] = (long long)p[1].x * p[1].sum;
for (int i = 2; i <= nn; i++)
{
if (p[i - 1].x == p[i].x - 1)
a[i] = max(a[i - 1], a[i - 2] + p[i].x * p[i].sum);
else
a[i] = a[i - 1] + p[i].x * p[i].sum;
}
}
cout << a[nn] << endl;
system("Pause");
}