Codeforces Round #260 (Div. 2) C

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;
}


你可能感兴趣的:(dp,codeforces)