week10——C - 拿数问题 II

题目

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;
}

猜你喜欢

转载自blog.csdn.net/alicemh/article/details/105799838