Week 10 作业 C - 拿数问题II CodeForces - 455A

题目描述:

YJQ 上完第10周的程序设计思维与实践后,想到一个绝妙的主意,他对拿数问题做了一点小修改,使得这道题变成了 拿数问题 II。

给一个序列,里边有 n 个数,每一步能拿走一个数,比如拿第 i 个数, Ai = x,得到相应的分数 x,但拿掉这个 Ai 后,x+1 和 x-1 (如果有 Aj = x+1 或 Aj = x-1 存在) 就会变得不可拿(但是有 Aj = x 的话可以继续拿这个 x)。求最大分数。

思路:

  • 因为要求拿到的数总和最大,所以可以认为所有的数都是正整数,因为即使有负数,也不可能去拿负数,而且如果序列中有多个相同的X,则如果拿了其中一个X,则其他X一定也要拿
  • 把这个问题转化为普通的拿数问题,可以认为有10^5个数,从1-10^5,如果i在序列中,则其表示的数是i*fre(fre是i在序列中出现的次数);如果i不在序列中,则其表示的数就是0

代码:

#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const int MAXN=1e5+5;
ll cnt[MAXN];
ll dp[MAXN];
int main()
{
	int N; cin>>N;
	for(int i=1;i<=N;i++)
	{
		int x;
		scanf("%d",&x);
		cnt[x]+=x;
	}
	dp[1]=cnt[1];
	for(int i=2;i<MAXN;i++)
	{
		dp[i]=max(dp[i-1],dp[i-2]+cnt[i]);
	}
	cout<<dp[MAXN-1]<<endl;
	return 0;
}

  

posted @ 2020-05-20 12:23  菜鸡今天学习了吗  阅读(143)  评论(0编辑  收藏  举报