线性dp Codeforces Round #260 (Div. 1) A题 Boredom

Boredom

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 a k) and delete it, at that all elements equal to a k + 1 and a k - 1 also must be deleted from the sequence. That step brings a k points to the player.

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


题目大意:给你一个长度为n的序列 a,你每次能取序列里面的一个数 a[i](得到a[i]分数),并且序列里面 a[i]-1 和 a[i]+1 的个数都要减一(如果个数为0,那就不减),问最后能得到的最大分数;

首先要明白,一个数 a[i] 要取,一定是把这个序列的所有 a[i] 都取掉,要不就不取 a[i] ;

现在要判断的就是存不存在 a[i] 和 a[i]-1 或者 a[i]+1 一起取?

不存在,可以发现如果:

  1. a[i] 的个数比 a[i]-1 大,取了 a[i],a[i]-1 的个数就没有了;
  2. a[i] 的个数比 a[i]-1 小,取了 a[i],a[i]-1 的个数有,但是之前在计算 a[i]-1 时如果取了a[i]-1,那么 a[i] 的个数就没有了;
  3. a[i] 的个数和 a[i]-1 一样,那和第一种情况一样;

所以如果 a[i] 取,那么 a[i]-1 就一定不能取,状态要从 a[i]-2 转化过来;

代码:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100100;
const int M=2000100;
const LL mod=1e9+7;
int a[N],sum[N],mx;
LL dp[N],ans;
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum[a[i]]++;
		mx=max(mx,a[i]);
	}
	ans=dp[1]=sum[1];
	for(int i=2;i<=mx;i++){
		dp[i]=max(dp[i-1],dp[i-2]+(LL)i*(LL)sum[i]);
		ans=max(dp[i],ans);
	}
	cout<<ans<<endl;
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值