拿数问题
题目描述
给定 n 个数,我们要从中选出多若干个数,其中任意大小不同的两数差的绝对值不能为 1,那么选出的数之和最大是多少。
输入格式
第一行一个整数 n 。
第二行 n 个整数,a1,a2,…,an ,表示这 n 个数
输出格式
一个整数,选出的数的和的最大值
测试样例
样例输入
5
1 1 3 2 3
样例输出
8
数据规模
对于 100% 的数据,1≤n≤106,1≤* a i a_i ai*≤106
这是一个经典的原数组的值直接当作下标来求解
定义数组 a ,他的元素值的意义是下标为 i 的数在这 n 个数里面出现了多少次
如果选了下标为 i 的数,和就应该加上 a[i] * i,其中 a[i] 是 i 在 在原数组中出现了几次
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[10000000] = {0}; //下标是元素值,数组的值是这个元素在输入的数中出现的个数
ll dp[10000000] = {0};
int main()
{
ll n;
cin >> n;
ll m = 0;
for (ll i = 0; i < n; i++)
{
ll t;
cin >> t;
m = max(m, t);
a[t] += 1;
}
dp[1] = a[1];
for (ll i = 1; i <= m; i++)
dp[i] = max(dp[i - 1], dp[i - 2] + a[i] * i);//要么选当前数的前一个数,要么选当前数和当前数的前面的前面的数
cout << dp[m];
return 0;
}