【LeetCode】Entrenamiento de programación dinámica (6)

123. Mejor momento para comprar y vender acciones III

Haga clic para ver: Mejor momento para comprar y vender acciones III


Dada una matriz cuyo i-ésimo elemento es el precio de una acción dada en el día i.
Diseñe un algoritmo para calcular la ganancia máxima que puede obtener. Puede completar hasta dos transacciones.
Nota: no puede participar en varias transacciones al mismo tiempo (debe vender las acciones anteriores antes de volver a comprar).

Ejemplo 1:
Entrada: precios = [3,3,5,0,0,3,1,4]
Salida: 6
Explicación: comprar el día 4 (precio de las acciones = 0), comprar el día 6 (venta de las acciones cuando el precio = 3), esta transacción puede generar una ganancia = 3-0 = 3.
Entonces, comprando el 7.º día (precio de las acciones = 1) y vendiendo el 8.º día (precio de las acciones = 4), esta transacción puede generar una ganancia = 4-1 = 3.
Ejemplo 2:
Entrada: precios = [1,2,3,4,5]
Salida: 4
Explicación: Compre el día 1 (precio de las acciones = 1), compre el día 5 (precio de las acciones = 5) Venta, esta transacción puede hacer una ganancia = 5-1 = 4.
Tenga en cuenta que no puede comprar acciones en el Día 1 y el Día 2 de forma consecutiva y venderlas más tarde.
Debido a que esto implica múltiples transacciones al mismo tiempo, debe vender las acciones anteriores antes de volver a comprar.

análisis de tema

En comparación con la emisión de acciones anterior, excepto por la tarifa de manejo y el período de congelación, la mayoría de los demás son iguales,
pero la cantidad de transacciones se puede cambiar de una a dos (hasta dos, o una o cero)

Desde la compra de acciones hasta la venta de acciones, se considera que se completa una transacción


transacción cero

Dado que los precios están en orden descendente, no importa cuándo compre acciones, perderá dinero cuando las venda. Por lo tanto,
durante este período, si no hace nada, la ganancia en este momento es: 0 y
cero transacciones se completan en este momento. tiempo

Un trato

Cuando el precio esté en orden ascendente, venda las acciones el primer día, no haga nada hasta que el precio sea 5,
venda las acciones cuando el precio sea 5 y la ganancia en este momento sea: 5-1=4
Complete una transacción en esta vez el comercio


dos tratos

Si compra acciones el primer día, no habrá ganancias si las compra el segundo día, por lo que no hace nada el segundo día. El tercer día, vende las
acciones. La ganancia en este momento es: 5-3=2


Compre las acciones el cuarto día y permanezca en un estado de no hacer nada hasta que el precio sea de 4 yuanes.
Cuando el precio sea de 4 yuanes, venda las acciones.
La ganancia en este momento es: 4-0 = 4
La suma de las dos transacciones completadas La ganancia es: 4+2=6

Complete dos transacciones en este momento

ecuación de transición de estado

dp[i]: indica el beneficio máximo que se puede obtener después del final del i-ésimo día


En la posición i, hay dos estados, estado de compra y estado de venta.
Utilice f para representar el estado de compra y g para representar el estado de venta.
i representa el final del día i
y j representa el número de transacciones

f[i][j]: significa que después del final del i-ésimo día, se han completado j transacciones, y la ganancia máxima en este momento es g[i][j]: significa que desde el final del i -th día, la transacción se ha
completado j transacciones, en el estado de venta, la ganancia máxima en este momento

Después de completar la operación de compra y venta de acciones, se cambiará el número de transacciones.


f[i][j] ecuación de transición de estado

Si el día i-1 está en estado de compra, no haga nada el día i-ésimo, y el día i-ésimo también está en estado de compra. En este caso: f[i][
j ]=f[i- 1][j];


Si el día i-1 está en estado de venta, entonces el día i-ésimo está en estado de compra.
Debe restar el precio[i] correspondiente a la compra de la acción.
En este caso: f[i][j] =g[i-1][ j]-precio[i];


La ecuación de transición de estado es:
f[i][j]=max(f[i-1][j],g[i-1][j]-price[i]);

g[i][j] ecuación de transición de estado

Si el día i-1 está en estado de venta, no haga nada en el día i-ésimo, entonces el día i-ésimo también está en estado de venta. En este caso: g[i][j
] =g[i- 1][j] ;


Si el día i-1 está en estado de compra, entonces el día i-ésimo está en estado de venta.Se
debe sumar el precio de beneficio[i] correspondiente a la venta de acciones,
porque se completa el estado de compra a venta, el número de transacciones en el i-th día +1 se convierte en j. En este momento, j es +1 en el número original de veces
y el número de transacciones en el i-1th día sigue siendo el número original de veces. debe ser j-1
desde la compra de acciones hasta la venta de acciones. Calcule la finalización de una transacción
suponiendo que j es 0, luego compre acciones el día i-1, el número de transacciones es 0
y venda acciones el día i-ésimo, el número de transacciones es 1

En este caso: g[i][j]=f[i-1][j-1]+precio[i];


La ecuación de transición de estado es:
g[i][j]= max(g[i-1][j],f[i-1][j-1]+precio[i]);

inicialización

Para la ecuación de transición de estado de g[i][j], cuando j es 0, -1 transacción se completa en el día i-1, esta situación no existe, por lo que el estado de g[i][j] puede
ser La ecuación de transferencia se modifica


En el primer paso, asigne g[i][j] a g[i-1][j], así que reemplace directamente g[i-1][j] con g[i][j en el ciclo if] En
este manera, -1 transacciones pueden ser evitadas


La ordenada indica que después del final del i-ésimo día,
la abscisa indica la finalización de la transacción i
. Cuando la ordenada es 0, significa que 0/1/2 transacciones se completan después del final del día 0. Esto situación no existe Compra
y venta en el mismo día, no hay ganancias, y el número de transacciones es limitado,
por lo que para no interferir con los resultados posteriores, después del final del día 0, cuando 1/2 transacciones se completan, todos se establecen en infinito negativo


f[0][0]: Indica que después del final del día 0, está en estado de compra, es decir, comprar la acción costará dinero y la ganancia será negativa f[0][0]=
- precio[0];


g[0][0]: Indica que después del final del día 0, está en estado de venta (después del final del día 0, no hay existencias disponibles y no se puede vender, lo que equivale a sin hacer nada, y la ganancia es 0) g[
0 ][0]=0;


Si selecciona INT_MIN para infinito negativo,
se producirá un problema fuera de los límites Selección de infinito negativo -0x3f3f3f3f(0x3f3f3f3f es la mitad del valor máximo de int)

código completo

class Solution {
    
    
public:
    int maxProfit(vector<int>& prices) {
    
    
       int n=prices.size();
       //因为可能完成 0 1 2 三笔交易其中一种 所以定义为3列
       //负无穷大 若要设置为INT_MIN会发生越界问题
       //所以使用 -0x3f3f3f
       vector<vector<int>>f(n,vector<int>(3,-0x3f3f3f3f));
       vector<vector<int>>g(n,vector<int>(3,-0x3f3f3f3f));
       int i=0;
       int j=0;
       //初始化
       f[0][0]=-prices[0];
       g[0][0]=0;
       for(i=1;i<n;i++)
       {
    
    
           for(j=0;j<3;j++)
           {
    
    
               f[i][j]=max(f[i-1][j],g[i-1][j]-prices[i]);
               //修改后的状态转移方程 
               g[i][j]=g[i-1][j];
               if(j-1>=0)
               {
    
    
                   g[i][j]=max(g[i][j],f[i-1][j-1]+prices[i]);
               }
           }
       }
       int ret=INT_MIN;
        //寻找最后一行g的最大值
        for(j=0;j<3;j++)
        {
    
    
            if(ret<g[n-1][j])
            {
    
    
                 ret=g[n-1][j];
            }
        }
        //返回最后一行g的最大值
        return ret;
    }
};

Valor devuelto
Dado que la ganancia máxima puede ser 0 transacciones/1 transacción/2 transacciones
Si se usa f, significa que ha alcanzado la última posición y todavía está en el estado de compra, por lo que no puede ser la ganancia máxima, así que
use g y contar el último de g El valor máximo de una fila (posición 0,1,2)

188. Mejor momento para comprar y vender acciones IV

Haga clic para ver: Mejor momento para comprar y vender acciones IV


Dada una matriz de enteros prices, su i-ésimo elementoprices[i] es el precio de una acción dada en el día i, y un entero k.
Diseñe un algoritmo para calcular la ganancia máxima que puede obtener. Puede completar como máximo k transacciones. En otras palabras, puede comprar k veces como máximo y vender k veces como máximo.
Nota: no puede participar en varias transacciones al mismo tiempo (debe vender las acciones anteriores antes de volver a comprar).

Ejemplo 1:
Entrada: k = 2, precios = [2,4,1]
Salida: 2
Explicación: comprar el día 1 (precio de las acciones = 2), comprar el día 2 (precio de las acciones = 4) Venta, esta transacción puede hacer una ganancia = 4-2 = 2.
Ejemplo 2:
Entrada: k = 2, precios = [3,2,6,5,0,3]
Salida: 7
Explicación: comprar el día 2 (precio de las acciones = 2), comprar el día 3 (venta de las acciones cuando precio = 6), esta transacción puede generar ganancias = 6-2 = 4.
Luego, compre el quinto día (precio de las acciones = 0) y venda el sexto día (precio de las acciones = 3), esta transacción puede generar ganancias = 3-0 = 3.

análisis de tema

Esta pregunta es básicamente similar al mejor momento para comprar y vender acciones III, excepto que el máximo anterior de 2 veces (0 1 2 tres posibilidades) se ha cambiado a k veces ([0,k-1] posibilidades


k es 2, lo que significa como máximo 2 transacciones (0 transacción/1 transacción/2 transacciones son tres posibilidades) para buscar el máximo beneficio


Compre acciones el primer día y véndalas el segundo día, la ganancia en este momento es: 4-2=2
El tercer día es el último día, así que no haga nada,
es decir, la ganancia máxima es: 2

ecuación de transición de estado

(La pregunta sobre el mejor momento IV es básicamente la misma que la pregunta sobre el mejor momento III en la etapa de análisis)


dp[i]: indica el beneficio máximo que se puede obtener después del final del i-ésimo día

En la posición i, hay dos estados, estado de compra y estado de venta.
Utilice f para representar el estado de compra y g para representar el estado de venta.
i representa el final del día i
y j representa el número de transacciones

f[i][j]: significa que después del final del i-ésimo día, se han completado j transacciones, y la ganancia máxima en este momento es g[i][j]: significa que desde el final del i -th día, la transacción se ha
completado j transacciones, en el estado de venta, la ganancia máxima en este momento

Después de completar la operación de compra y venta de acciones, se cambiará el número de transacciones.

f[i][j] ecuación de transición de estado

Si el día i-1 está en estado de compra, no haga nada el día i-ésimo, y el día i-ésimo también está en estado de compra. En este caso: f[i][
j ]=f[i- 1][j];


Si el día i-1 está en estado de venta, entonces el día i-ésimo está en estado de compra.
Debe restar el precio[i] correspondiente a la compra de la acción.
En este caso: f[i][j] =g[i-1][ j]-precio[i];


La ecuación de transición de estado es:
f[i][j]=max(f[i-1][j],g[i-1][j]-price[i]);

g[i][j] ecuación de transición de estado

Si el día i-1 está en estado de venta, no haga nada en el día i-ésimo, entonces el día i-ésimo también está en estado de venta. En este caso: g[i][j
] =g[i- 1][j] ;


Si el día i-1 está en estado de compra, entonces el día i-ésimo está en estado de venta.Se
debe sumar el precio de beneficio[i] correspondiente a la venta de acciones,
porque se completa el estado de compra a venta, el número de transacciones en el i-th día +1 se convierte en j. En este momento, j es +1 en el número original de veces
y el número de transacciones en el i-1th día sigue siendo el número original de veces. debe ser j-1
desde la compra de acciones hasta la venta de acciones. Calcule la finalización de una transacción
suponiendo que j es 0, luego compre acciones el día i-1, el número de transacciones es 0
y venda acciones el día i-ésimo, el número de transacciones es 1

En este caso: g[i][j]=f[i-1][j-1]+precio[i];


La ecuación de transición de estado es:
g[i][j]= max(g[i-1][j],f[i-1][j-1]+precio[i]);

inicialización

Para la ecuación de transición de estado de g[i][j], cuando j es 0, -1 transacción se completa en el día i-1, esta situación no existe, por lo que el estado de g[i][j] puede
ser La ecuación de transferencia se modifica


En el primer paso, asigne g[i][j] a g[i-1][j], así que reemplace directamente g[i-1][j] con g[i][j en el ciclo if] En este manera, -1 transacciones
pueden ser evitadas


Suponiendo que k es 2, hay tres situaciones: 0 transacciones, 1 transacción, 2 transacciones

La ordenada indica que después del final del i-ésimo día,
la abscisa indica la finalización de la transacción i
. Cuando la ordenada es 0, significa que 0/1/2 transacciones se completan después del final del día 0. Esto situación no existe Compra
y venta en el mismo día, no hay ganancias, y el número de transacciones es limitado,
por lo que para no interferir con los resultados posteriores, después del final del día 0, cuando 1/2 transacciones se completan, todos se establecen en infinito negativo


f[0][0]: Indica que después del final del día 0, está en estado de compra, es decir, comprar la acción costará dinero y la ganancia será negativa f[0][0]=
- precio[0];


g[0][0]: Indica que después del final del día 0, está en estado de venta (después del final del día 0, no hay existencias disponibles y no se puede vender, lo que equivale a sin hacer nada, y la ganancia es 0) g[
0 ][0]=0;


Si se selecciona int_min para infinito negativo, se producirá un
problema fuera de los límites. Selección de infinito negativo -0x3f3f3f3f(0x3f3f3f3f es la mitad del valor máximo de int)\

código completo

class Solution {
    
    
public:
    int maxProfit(int k, vector<int>& prices) {
    
    
       int n=prices.size();
       //将k进行优化
       k=min(k,n/2);
         //f 表示买入状态 g表示卖出状态
       //有[0,k-1] 笔交易
       vector<vector<int>>f(n,vector<int>(k+1,-0x3f3f3f));  
       vector<vector<int>>g(n,vector<int>(k+1,-0x3f3f3f));

       //初始化
       f[0][0]=-prices[0];
       g[0][0]=0;
       int i=0;
       int j=0;
       for(i=1;i<n;i++)
       {
    
    
           for(j=0;j<=k;j++)
           {
    
    
              f[i][j]=max(f[i-1][j],g[i-1][j]-prices[i]);
            //修改后的状态转移方程
              g[i][j]=g[i-1][j];
              if(j-1>=0)
              {
    
    
                  g[i][j]=max(g[i][j],f[i-1][j-1]+prices[i]);
              }
           }
       }
       //寻找g的最后一行的最大值
       int ret=INT_MIN;
       for(j=0;j<=k;j++)
       {
    
    
           if(ret<g[n-1][j])
           {
    
    
               ret=g[n-1][j];
           }
       }
       //返回g的最后一行的最大值
       return ret;
    }
};

Si hay 20 días, k (cantidad de transacciones) es 30,
y la cantidad máxima de transacciones es solo 10, entonces optimice
k=min(k,n/2);
(n/2 representa la cantidad máxima de transacciones)

53. Suma máxima de subarreglo

Haga clic para ver: Suma máxima de subarreglo


ecuación de transición de estado

Obtenga todas las sub-matrices que terminan con i, tales como: posición i, combinación de posición i e i-1, combinación de posición i e i-2, combinación de posición i y subíndice 0, etc. Tome el subíndice generado -arreglos entre
ellos y el más grande

dp[i]: indica la suma máxima de todos los subarreglos que terminan en el elemento de posición i


dp[i] se puede dividir en dos categorías:

1. El elemento de posición i en sí mismo (la longitud es 1)
en este caso: dp[i]= nums[i]


2. El elemento de posición i se combina con el elemento anterior (longitud mayor que 1)

Debido a que lo que se requiere es la suma máxima de los subconjuntos que terminan en la posición i, primero debe encontrar la suma máxima de los subconjuntos que terminan en la posición i-1, es decir, agregue nums[i] a dp[i- 1], que
es La posición i es la suma máxima de sub-matrices al final
En este caso: dp[i]=dp[i-1]+nums[i];

inicialización

Si i es 0, es un problema fuera de límites

Para evitar este tipo de problema fuera de los límites, se agrega un nodo virtual a
la matriz expandida. El subíndice del nodo virtual es 0 y el subíndice del elemento de la matriz original comienza en 1.

Si es dp[1], dp[1]=max(nums[1],dp[0]+nums[1])
para no interferir con el resultado , establezca el valor de dp[0] en 0

código completo

class Solution {
    
    
public:
    int maxSubArray(vector<int>& nums) {
    
    
       int n=nums.size();
       //dp作为扩展数组 所以比原数组大1
       vector<int>dp(n+1,0);

       int i=0;
       //因为dp表可能都为负,所以初始值为最小值
       int ret=INT_MIN;
       for(i=1;i<n+1;i++)
       {
    
    
           //当前下标i作为扩展数组dp的下标 
           //想要使用dp下标 找到对应 原数组nums对应值
           //应该使用i-1
           dp[i]=max(nums[i-1],dp[i-1]+nums[i-1]);
           //寻找dp表的最大值
           if(ret<dp[i])
           {
    
    
               ret=dp[i];
           }
       }

       return ret;

    }
};

Supongo que te gusta

Origin blog.csdn.net/qq_62939852/article/details/131462419
Recomendado
Clasificación