金苹果岛 - 代码能力最大化
金苹果岛 - 代码能力最大化
题目描述
代码勇者来到了金苹果岛上,金苹果岛上有两种苹果:随处可见的红苹果与稀有美味的金苹果。
勇者的'初始代码能力为 1',他每吃下一个红苹果,代码能力就会得到一定程度的提升(每个红苹果带来的提升可能是不同的,甚至也可能是负的);他每吃下一个金苹果,代码能力就会直接'翻倍'(每个金苹果的效果都是完全相同的)。
岛上的苹果仙子用 n 个红苹果和 m 个金苹果招待了勇者,勇者必须吃光所有苹果。勇者必须按照仙子'规定的顺序'吃红苹果,但是他可以'自由安排'什么时候吃金苹果(可以在吃'任意'一个红苹果之前或之后吃'若干'个金苹果)。
求勇者在离开金苹果岛的时候的代码能力的最大值。
输入格式
第一行输入两个正整数 n(n≤10^5)和 m( m≤10)。
第二行输入 n 个整数 a_i(|a_i|≤10)。
输出格式
输出一个整数,表示勇者在离开金苹果岛的时候的代码能力的最大值。
样例 #1
样例输入 #1
6 2
1 -2 3 1 -6 5
样例输出 #1
15
样例 #2
样例输入 #2
8 3
5 -3 -8 2 4 -11 9 1
样例输出 #2
42
提示
样例1解释
勇者吃掉红苹果 1,-2,3,1,代码能力变为 4;
勇者吃掉 2 颗金苹果,代码能力变为 16;
勇者吃掉红苹果 -6,5,代码能力变为 15。
这是勇者的最优方案。
子任务
对于 10% 的数据,a_i≥0;
对于 30% 的数据,m=0;
对于 70% 的数据,m=1;
对于 100% 的数据,n≤10^5,m≤10,|a_i|≤10。
贪心算法
由于金苹果可以随时吃,并且会将代码能力翻倍,因此最佳策略是:
- 将所有红苹果按提升代码能力值的大小进行排序。
- 从最小的提升能力值开始,如果当前红苹果的提升能力值为负数,且还有剩余金苹果,则吃掉一个金苹果,将当前红苹果的提升能力值变成正数;否则,直接吃掉当前红苹果。
- 最后,将所有红苹果的提升能力值加起来,再乘以 2 的金苹果数量次方,即为最终代码能力的最大值。
C++ 代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<int> apples(n);
for (int i = 0; i < n; i++) {
cin >> apples[i];
}
sort(apples.begin(), apples.end());
long long ans = 0;
for (int i = 0; i < n; i++) {
if (apples[i] < 0 && m > 0) {
m--;
} else {
ans += apples[i];
}
}
ans *= pow(2, m);
cout << ans << endl;
return 0;
}
代码解析
- 输入红苹果数量 n 和金苹果数量 m,以及每个红苹果的提升能力值 a_i。
- 将红苹果的提升能力值按从小到大排序。
- 遍历排序后的红苹果,如果当前红苹果的提升能力值为负数,且还有剩余金苹果,则吃掉一个金苹果,将当前红苹果的提升能力值变成正数。否则,直接吃掉当前红苹果。
- 计算所有红苹果的提升能力值之和,并乘以 2 的金苹果数量次方,即为最终代码能力的最大值。
总结
该贪心算法通过将红苹果按提升能力值从小到大排序,并合理使用金苹果,可以有效地找到最终代码能力的最大值。
注意:
- 本题中的代码能力值可以为负数,需要考虑如何利用金苹果将负数提升能力值变成正数。
- 金苹果的数量有限,需要在使用金苹果时进行判断,避免浪费。
原文地址: https://www.cveoy.top/t/topic/fM1u 著作权归作者所有。请勿转载和采集!