week10-拿数问题II

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你能得到最大分值。

思路:

因为课上题目拿数之后数组中相邻数不可拿,但是在这里是按照大小的”相邻“,所以考虑直接对数进行排序,从而转换成数组中的相邻。

还需要注意一个数可能存在很多个,这些都是可以继续拿的。

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 const int maxn = 1e5+10;
 6 
 7 int a[maxn];
 8 int n;
 9 long long dp[maxn];
10 long long time[maxn];
11 int l=maxn,r=0;
12 
13 int main()
14 {
15     ios::sync_with_stdio(false);
16     cin>>n;
17     for(int i=1;i<=n;++i)
18     {
19         cin>>a[i];
20         l = min(l,a[i]);
21         r = max(r,a[i]);
22         time[a[i]]++;
23     }
24     dp[l] = l * time[l];
25     dp[0]=0;
26     if(l==1)l++;
27     for(long long i=l;i<=r;++i)
28         dp[i]=max(dp[i-1],dp[i-2]+i*time[i]);
29 
30     cout<<dp[r];
31     
32     return 0;
33 }

 

posted @ 2020-06-06 09:11  流转~星云  阅读(124)  评论(0编辑  收藏  举报