题面描述

Alex doesn't like boredom. That's why whenever he gets bored, he comes up with games. One long winter evening he came up with a game and decided to play it.

亚历克斯不喜欢无聊。这就是为什么每当他感到无聊时,他就会想出一些游戏。在一个漫长的冬日傍晚,他想出了一个游戏并决定玩它。

Given a sequence a consisting of n integers. The player can make several steps. In a single step he can choose an element of the sequence (let's denote it ak) and delete it, at that all elements equal to ak + 1 and ak - 1 also must be deleted from the sequence. That step brings ak points to the player.

给定一个由n个整数组成的序列。玩家可以做几个步骤。在单个步骤中,他可以选择序列的元素(假设为\(a_k\))并删除它,此时,所有等于\(a_k+1和a_k-1\)的元素也必须从序列中删除。这个步骤给玩家带来\(a_k\)点数。

Alex is a perfectionist, so he decided to get as many points as possible. Help him.

亚历克斯是个完美主义者,所以他决定得到尽可能多的分数。帮助他。

输入格式

The first line contains integer n (1 ≤ n ≤ 105) that shows how many numbers are in Alex's sequence.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 105).

第一行包含一个整数n(\(1≤n≤105\)),表示Alex序列中有多少个数字。

第二行包含n个整数\(a1,a2,…,an(1≤105)\)

输出格式

输出一个整数——Alex可以获得的最大点数

样例

样例输入

9

1 2 1 3 2 2 2 2 3

样例输出

10

题解

先求出数列中每一个数字k的出现次数num[k]

考虑取任意一个数\(x\)时只会影响到\(x+1\)和\(x-1\),我们可以先设dp[i]表示选取num后可以取得的最大值。因为任意取两个数\(a和b\),若选取\(a\)后可以选取\(b\),则选取\(b\)后可以选取\(a\),因此我们只考虑\(x与x-1\)之间的关系。这样我们就很容易得到递推式:

\[dp[i]=\begin{cases}
0 && i=0\\
num[1]*1 && i=1\\
max(dp[i-1],dp[i-2]+num[i]*i) && else
\end{cases}
\]

注意,最后一重for循环要从2循环至已知的maxn

#include<bits/stdc++.h>
#define maxn 1000050
using namespace std;
inline char get(){
static char buf[3000],*p1=buf,*p2=buf;
return p1==p2 && (p2=(p1=buf)+fread(buf,1,3000,stdin),p1==p2)?EOF:*p1++;
}
inline long long read(){
register char c=getchar();register long long f=1,_=0;
while(c>'9' || c<'0')f=(c=='-')?-1:1,c=getchar();
while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=getchar();
return _*f;
}
long long note,n,a[maxn],dp[maxn];
long long op=0;
int main(){
//freopen("1.txt","r",stdin);
n=read();
for(register long long i=1;i<=n;i++)a[i]=read(),dp[a[i]]+=a[i],note=max(note,a[i]);
for(register long long i=2;i<=note;i++)dp[i]=max(dp[(i)-1],dp[(i)-2]+dp[i]),op=max(dp[i],op);
cout<<op<<endl;
return 0;
}

最新文章

  1. prototype,__proto__,constructor
  2. hellocharts包的使用心得
  3. 【XLL 框架库函数】 TempActiveCell/TempActiveCell12
  4. php常用的数组函数
  5. ssm maven项目启动 报SYSTEM_PROPERTIES_MODE_ENVIRONMENT
  6. mac 安装tomcat
  7. 在线教学、视频会议 Webus Fox(2) 服务端开发手册
  8. hdu1247 字典树
  9. codevs 1201 最小数和最大数
  10. Julia中文教程资源.txt
  11. dataguru试听课程
  12. inux xsel 拷贝复制命令行输出放在系统剪贴板上
  13. java打印日历
  14. WPF 读写TxT文件
  15. ASP.NET MVC应用程序实现下载功能
  16. USB设备驱动概述
  17. 利用express托管静态文件
  18. 为什么JS事件函数里面都有一个参数(ev)?
  19. spring jdbc配置文件进行加密解密
  20. 【bzoj4541】 Hnoi2016—矿区

热门文章

  1. DB2 编目并访问远程数据库
  2. Jmeter--JDBC请求(sqlserver)
  3. linux VMware使用
  4. Oracle 体系结构二 内存结构
  5. Oracle常用内置函数
  6. HTML基础之常用标签
  7. LeetCode 中级 - 优势洗牌(870)
  8. 自动曝光修复算法 附完整C代码
  9. 判断FreeMarker是否为空
  10. 利用mysqlbinlog_flashback闪回丢失数据