C. Boredom
题意:给一串数,你对它执行若干次操作。每次操作可以任意删去一个数,比如k,同时值为k+-1的数全部要删去,该次操作你将得到k分。问到最后你最多得多少分。
思路:dp。比赛的时候脑残了开了dp[n][n]去区间dp爆内存,然后又以为是贪心,走上了不归路。其实dp[n][2]就好了。对每个可能的值计数,从小到大顺序删,dp(i,1)表示到i时删除i的情况下最大得分,dp(i,0)表示到i时不删除i的情况下最大得分。状态转移见代码。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#define INF 1000000
#define ll long long
#define min3(a,b,c) min(a,min(b,c))
using namespace std;
long long cnt[100010];
long long dp[100010][2];
int main(){
int n;
while(cin>>n){
memset(cnt,0,sizeof(cnt));
memset(dp,0,sizeof(dp));
int num;
for(int i=1;i<=n;i++){
scanf("%d",&num);
cnt[num]++;
}
for(long long i=1;i<=100000;i++){
dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
dp[i][1]=dp[i-1][0]+cnt[i]*i;
}
cout<<max(dp[100000][1],dp[100000][0])<<endl;
}
return 0;
}