線性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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章