金苹果岛 - 代码能力最大化问题

代码勇者来到了金苹果岛上,金苹果岛上有两种苹果:随处可见的红苹果与稀有美味的金苹果。

勇者的'初始代码能力为 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。

解题思路

对于每个红苹果,我们有两种选择:吃它或者不吃它。如果我们吃了它,我们的代码能力将会增加 a_i;如果我们不吃它,我们的代码能力将会保持不变。因此,我们可以使用动态规划来解决这个问题。

假设我们有一个长度为 n 的数组 dp,其中 dp[i] 表示在吃完第 i 个红苹果后的代码能力的最大值。那么我们可以得到以下状态转移方程:

dp[i] = max(dp[i-1] + a_i, dp[i-1])

其中 dp[0] 表示初始的代码能力,即 1。

接下来,我们需要考虑金苹果的使用。由于金苹果的效果是直接翻倍的,我们可以在任意一个红苹果之前或之后使用若干个金苹果。因此,我们可以用一个变量 max_dp 来记录在遍历红苹果时的最大的代码能力值。

具体的算法如下:

  1. 初始化 dp[0] 为 1,max_dp 为 1。
  2. 遍历红苹果,从 1 到 n:
    • 更新 dp[i],根据状态转移方程 dp[i] = max(dp[i-1] + a_i, dp[i-1])。
    • 更新 max_dp,如果 dp[i] 大于 max_dp,则更新 max_dp。
  3. 将 max_dp 乘以 2^m,得到最终的代码能力的最大值。

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];
    }
    
    vector<int> dp(n);
    dp[0] = 1;
    int max_dp = 1;
    
    for (int i = 1; i < n; i++) {
        dp[i] = max(dp[i-1] + apples[i], dp[i-1]);
        max_dp = max(max_dp, dp[i]);
    }
    
    int max_ability = max_dp * (1 << m);
    cout << max_ability << endl;
    
    return 0;
}

该算法的时间复杂度为 O(n)。

金苹果岛 - 代码能力最大化问题

原文地址: https://www.cveoy.top/t/topic/fM1c 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录