题目
YJQ 上完第10周的程序设计思维与实践后,想到一个绝妙的主意,他对拿数问题做了一点小修改,使得这道题变成了 拿数问题 II。
给一个序列,里边有 n 个数,每一步能拿走一个数,比如拿第 i 个数, Ai = x,得到相应的分数 x,但拿掉这个 Ai 后,x+1 和 x-1 (如果有 Aj = x+1 或 Aj = x-1 存在) 就会变得不可拿(但是有 Aj = x 的话可以继续拿这个 x)。求最大分数。
本题和课上讲的有些许不一样,但是核心是一样,需要你自己思考。
Input
第一行包含一个整数 n (1 ≤ n ≤ 105),表示数字里的元素的个数
第二行包含n个整数a1, a2, …, an (1 ≤ ai ≤ 105)
Output
输出一个整数:n你能得到最大分值。
思路
a[i]记录数字i在数组中出现的个数
将dp[i]转化为仅考虑数字1~i,能拿到的最大分数
dp[i]=max(dp[i-1],dp[i-2]+a[i]*i)
错误
1、注意应该用long long 储存数组
代码
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=1e5+10;
long long a[maxn]={
0};
long long dp[maxn];
int main()
{
long long n,tmp,maxx=0;
memset(a,0,sizeof(a));
cin>>n;
for(int i=0;i<n;i++)
{
cin>>tmp;
a[tmp]++;
if(maxx<tmp)
maxx=tmp;
}
dp[0]=0;
dp[1]=a[1];
for(int i=2;i<=maxx;i++)
dp[i]=max(dp[i-1],dp[i-2]+a[i]*i);
cout<<dp[maxx]<<endl;
return 0;
}