题目链接:cf 455A
给你n个数,现在要求你从中删去一些数,使得任意两个数之间的的差值不为1,问剩下的数求和最大是多少
找出不重复的数,排序后作DP即可,状态转移方程:
dp[i]=dp[i-1]+sum[i] (|a[i]-a[i-1]|!=1)
dp[i]=max(dp[i-1],dp[i-2]+sum[i]) (|a[i]-a[i-1]|=1)
(sum[i]为第i种数的总和)
/*********************************************************************
FileName: c.cpp
Author: kojimai
Created Time: 2014年08月08日 星期五 23时53分33秒
*********************************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define FFF 100005
long long a[FFF],cnt[FFF],b[FFF],dp[FFF];
bool cmp(int x,int y)
{
return x>y;
}
int main()
{
int n;
scanf("%d",&n);
int ans=0;
memset(cnt,0,sizeof(cnt));
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
cnt[a[i]]++;//统计每个数出现了多少次
}
sort(a,a+n,cmp);
int now=0,tt=0;
int i=0;
while(i<n)
{
now=a[i];
b[tt++]=a[i];
while(a[i]==now&&i<n)
{
i++;
}
}
//for(int i=0;i<tt;i++)
//cout<<b[i]<<' ';cout<<endl;
dp[0]=0;
dp[1]=b[0]*cnt[b[0]];
//cout<<dp[1]<<endl;
for(int i=2;i<=tt;i++)
{
if(b[i-1]==b[i-2]-1)
{
//dp[i]=max(dp[i-1],dp[i-2]+b[i-1]*cnt[b[i-1]]);
dp[i]=max(dp[i-2]+b[i-1]*cnt[b[i-1]],dp[i-1]);
}
else
dp[i]=dp[i-1]+b[i-1]*cnt[b[i-1]];
}
cout<<dp[tt]<<endl;
return 0;
}