C++ --- Modelo de máquina de estado --- Comercio de acciones IV (Algoritmo Daily One 2023.4.12)

Nota:
Se recomienda comprender primero la definición básica de la máquina de estado: State Machine-Baidu Encyclopedia .

Pregunta:
Dada una matriz de longitud N, el i-ésimo número de la matriz representa el precio de una acción determinada en el día i.
Diseña un algoritmo para calcular la ganancia máxima que puedes obtener, puedes completar como máximo k transacciones.
Nota: no puede participar en varias transacciones al mismo tiempo (debe vender las acciones anteriores antes de volver a comprar). Una compra y venta se combinan en una sola transacción.

Formato de entrada
La primera línea contiene números enteros N y k, que indican la longitud de la matriz y el número máximo de transacciones que puede completar.
La segunda línea contiene N números enteros positivos que no superan los 10000, lo que representa una matriz completa.

Formato de salida
Muestra un número entero, que representa el beneficio máximo.

Rango de datos
1≤N≤105,
1≤k≤100

Ejemplo Explicación
Ejemplo 1: Compre el día 1 (precio de las acciones = 2) y venda el día 2 (precio de las acciones = 4), esta transacción puede generar ganancias = 4-2 = 2 .

输入:
3 2
2 4 1
输出:
2
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010, M = 110;
int n, m;
int f[N][M][2], w[N];       //w[i]为第i天 卖出/买入 的价格

int main() {
    
    
    cin >> n >> m;
    for (int i = 1; i<=n; i++) cin >> w[i];
    
    //根据实际意义出发,需要考虑所有 买入/卖出 的情况,f初始化负无穷,
    //如果初始值默认为0,那么f[i-1][j-1][0]-w[i]将永远比0小,永远都不会进行买入,
    //而我们需要求出所有情况,哪怕本次买入的策略对于当前这一步是亏损的, 这样才能根据这一步继续推导下一步。
    //有点类似深度学习路线计算的过程hh。
    memset(f, -0x3f3f, sizeof f);
    //根据实际意义出发,所有前i天总交易数为0且当前不持有股票时的收益全部为0是合法情况。
    for (int i = 0; i<=n; i++) f[i][0][0] = 0;
    
    //根据状态机分析进行状态转移
    for (int i = 1; i<=n; i++) {
    
    
        for (int j = 1; j<=m; j++) {
    
    
            f[i][j][0] = max(f[i-1][j][0], f[i-1][j][1]+w[i]);
            f[i][j][1] = max(f[i-1][j][1], f[i-1][j-1][0]-w[i]);
        }
    }
    
    //找到第n天不超过m笔交易的最大收益
    int res = 0;
    for (int i = 0; i<=m; i++) res = max(res, f[n][i][0]);
    cout << res << endl;
}

Idea:
sigue siendo el clásico método dp estilo y

1. Representación del estado Para
f[i][j][0]:
todos los esquemas cuando el número total de transacciones es anteayer y no se mantienen existencias actualmente, el atributo es Máx. Para anteayer , el número total de transacciones es (incluida la transacción de acciones que se tiene actualmente) y todos los planes cuando las acciones se mantienen actualmente, el atributo es Máx.ij
f[i][j][1]:
ij

2. Cálculo del estado
De acuerdo con la derivación de la máquina de estado, el stock actual en posesión/desposesión se divide en estados:
1. No hay ningún stock actualmente en posesión (se puede transferir desde dos estados):

  • No se mantuvieron acciones ayer:f[i-1][j][0]
  • Acciones retenidas ayer pero vendidas hoy:f[i-1][j][1]+w[i]

f[i][j][0] = max(f[i-1][j][0], f[i-1][j][1]+w[i])

2. Existencias actualmente en posesión (se pueden transferir desde dos estados):

  • Acciones mantenidas ayer:f[i-1][j][1]
  • No poseía acciones ayer pero compró hoy:f[i-1][j-1][0]-w[i]

f[i][j][1] = max(f[i-1][j][1], f[i-1][j-1][0]-w[i])

El dibujo de la máquina de estados es el siguiente (tomado del dibujo del patrón principal de color):
Por favor agregue una descripción de la imagen

Si es útil, por favor dale a Me gusta gratis ~ ¡Alguien mirando es la motivación para ayudarme a escribir!

Descargo de responsabilidad:
la fuente de la idea del algoritmo es el Sr. Y. Para obtener más detalles, consulte https://www.acwing.com/
Este artículo solo se usa para registros de aprendizaje e intercambios

Supongo que te gusta

Origin blog.csdn.net/SRestia/article/details/130111191
Recomendado
Clasificación