题意(Codeforces-455A)
给你(n)个数,你每次可以选择删除去一个数(x)获得(x)分,但是所有为(x+1)和(x-1)的数都得删去。问最大获得分数。
分析
这是一条经典dp。阶段是很自然的:我从左往右依次选择到每种数(先预处理在桶内),然后两个决策:拿,还是不拿(拿一定拿光)。拿,那么下一步就不能选择(x+1)了,直接选择(x+2);不拿,我可以选择(x+1)。两种情况取最大。
于是有状态转移方程:(dp[x]=max(dp[x-1], dp[x-2]+x*cnt_x))
代码
#include <bits/stdc++.h>
using namespace std;
long long arr[100005], dp[100005];
int main()
{
int n; cin>>n;
memset(arr,0,sizeof(arr));
for(int i=1;i<=n;++i)
{
int tmp; cin>>tmp;
arr[tmp]++;
}
dp[1]=arr[1]; dp[0]=0;
for(int i=2;i<=100000;++i)
{
dp[i]=max(dp[i-1], dp[i-2]+i*arr[i]);
}
cout<<dp[100000]<<endl;
return 0;
}