小游戏
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
有一个长度为 n 的数组 a[i] , 每一步能拿走一个数,比如拿第 i 个数, a[i] = x ,得到相应的分数 x ,但拿掉这个 x 后, x+1 和 x-1 (如果有 a[j] = x+1 或 a[j] = x-1 存在) 就会变得不可拿(但是有 a[j] = x 的话可以继续拿这个 x )。求最大分数。
输入描述:
第一行一个整数 n. ( 1 ≤ n ≤ 2e5)
第二行 n 个整数 a[i]. (0 ≤ a[i] ≤ 2e5)
输出描述:
输出能得到的最大分数。
示例1
输入
5 1 2 2 2 3
输出
6
说明
拿走 3 个 2
示例2
输入
3 1 2 3
输出
4
说明
拿走 1 和 3
思路:
看到题目想到的是dp 但是要如何找到状态转移方程呢
既然相同的数字可以同时拿起
那就对同个数字进行打表计和
然后从0开始到最大数字的下表
选3的同时可以决策 是否选1 和0
选2的同时只能决策是否选0
所以我们应该从2分
int n;
const int MAX=100010;
int a[MAX];
int dp[10000010];
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
dp[a[i]]+=a[i];
}
for(int i=0;i<2000000;i++){
if(i==2){
dp[i]+=dp[i-2];
}
else if(i>=3){
dp[i]+=max(dp[i-2],dp[i-3]);
}
}
int ans=0;
for(int i=0;i<200005;i++){
ans=max(ans,dp[i]);
}
cout<<ans;
}