zzuli 20级第七次周赛 2742 问题H : 法兰要塞

题目描述

“分享狼血,与子同胞”
“漫步深渊,心怀正义”
“侍奉光明,斩杀黑暗”
“因剑而生,因剑而死”
“深渊无尽,我等将不娶妻,不生子,只求一世荣耀”
“光阴有时,我等必守此誓,献此生,但愿诸界太平”
无火的余烬,你追随者古老的誓言来到了法兰要塞,为了通过烽火试炼,你必须收集足够多的灵魂。
已知要塞里有n个怪物,不同的怪物有着不同的血量a。每次,你可以选择消灭一只怪物,同时所有血量为a+1和a-1的怪物也会死去。同时你可以获得a个灵魂。

输入

第一行输入一个整数n(1<=n<=105)
第二行输入n个整数a1,a2,…an(1<=ai<=105)

输出

请输出无火的余烬可以获得的最大灵魂数量

样例输入

9
1 2 1 3 2 2 2 2 3

样例输出

10

提示

对于样例,第一次可以选择血量为2的怪物将其消灭。在这之后,我们的序列是这样的[2,2,2,2],然后可以再进行四次,每次选择一个血量为2的怪物消灭。最终我们能够获得10个灵魂。

思路:
动态规划思想。
可以想成如果杀血量为1的怪物,则不能杀血量为2的怪物,如果不杀血量为1的怪物,则血量为2的怪物,可以杀也可以不杀。
dp[i][0]是不杀该血量怪物的最大值,dp[i][1]是杀该血量怪物的最大值,如果杀了dp的值是,第i-1血量没杀的值加上i血量杀的值。如果不杀,dp的值第i-1血量没杀的值和i-1血量杀了的最大值。

#include <bits/stdc++.h>
using namespace std;

long long arr[100005];
long long dp[100005][2];

int main(){
	int n, a;
	cin>>n;
	memset(arr, 0, sizeof(arr));
	memset(dp, 0, sizeof(dp));
	// arr[n]  血量为n的灵魂数量  
	for(int i = 0; i < n; i++){
		scanf("%d", &a);
		arr[a] = arr[a] + a;
	}
	
	long long ans = 0;
	for(int i = 1; i < 100005; i++){
		dp[i][0] = max(dp[i-1][0], dp[i-1][1]);
		dp[i][1] = dp[i-1][0] + arr[i];
		ans = max(ans, dp[i][0]);
		ans = max(ans, dp[i][1]);
	}
	cout << ans;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值