Wandering --- 最后的编程挑战

要走N次:
样例:

3
2 -1 -2

————————————————
第一次走2
第二次 先走2 再走-1
第三次 先走2 再走-1 再走 -1
————————————————
从上面的三次行动中找出最远可以到的距离:
就变成了这样:

2 		———— 22
2 -1	———— 324,走到第三步仍需要选择 -13
2 -1 -1 ———— 525

可以发现,想走到第三步,必须将第2步全部走完。而我们要的是这些步中
最远的那个。
如果是普通算法,可以直接 O ( N 2 ) O(N^2) O(N2)遍历,但肯定是超时
所以我们有两个需要解决的问题:

  1. 每一步的最优解
  2. 怎么快速到达下一步
    即:
  3. 使用一个辅助数组,记录到i步的,最远的位置
  4. 快速到达下一步使用前缀和
    可以优化成 O ( N ) O(N) O(N)
#include <iostream>
using namespace std;
using LL = long long;
const int n = 200002;
LL a[n];
LL b[n];
int N;
int main()
{
    
    
    cin >> N;
    for (int i = 1; i <= N; i++)
        scanf("%lld", &a[i]), a[i] += a[i - 1], b[i] = max(b[i - 1], a[i]);
    // 答案
    LL maxt = 0;
    // 当前的位置
    LL sum = 0;
    for (int i = 1; i <= N; i++)
    {
    
    
        // 选择这次运动的最优位置
        maxt = max(maxt, sum + b[i]);
        // 如果要进行下次运动必要要将这次的全部走完
        sum = sum + a[i];
    }
    cout << maxt;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45653525/article/details/115437886