DP 概述

DP(Dynamic programming,全称动态规划),是一种基于分治,将原问题分解为简单子问题求解复杂问题的方法。

动态规划的耗时往往远少于朴素(爆搜)解法。

动态规划 and 递归

之前说过,动态规划也是分治思路,而递归更是传统的分治思路,但时间复杂度却大相径庭,为什么呢?

动态规划是

状态的定义

前言:空间换时间

很简单的名字,即为使用空间的代价来确保不会超时。

状态?

状态,通俗来讲就是你 分类讨论就是将问题通过不同的结果 / 形式 / 不同点分成几类逐个解决。

例题二思路

既然说到分类讨论我们先来分个类。

\(\max(\sum_{i = 1}^{N} A_i) = \begin{cases} C > 0 & \max(\sum_{i = L}^{R} A_i) \times C \\\\ C < 0 & \min(\sum_{i = L}^{R} A_i) \times C \end{cases}\)

最大最小怎么使用 \(O(N)\) 求?Bingo!最大 / 最小 子段和即可。

最后比一下就好了。

完整 Code:

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

#define ll long long
int n;
ll c;
ll a[100005];
ll solve()
{
    ll original_sum = 0;
    for (int i = 1; i <= n; ++i)
        original_sum += a[i];

    ll dp_max[100005], dp_min[100005];
    dp_max[1] = a[1];
    dp_min[1] = a[1];

    ll maxx = dp_max[1];
    ll minn = dp_min[1];

    for (int i = 2; i <= n; i++)
    {
        dp_max[i] = max(a[i], dp_max[i - 1] + a[i]);
        dp_min[i] = min(a[i], dp_min[i - 1] + a[i]);
        maxx = max(maxx, dp_max[i]);
        minn = min(minn, dp_min[i]);
    }

    ll res = max((c - 1) * maxx, (c - 1) * minn);
    ll ans = original_sum + res;
    return ans;
}

int main()
{
    cin >> n >> c;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    cout << solve() << endl;
    return 0;
}
10-27 15:17