Le meilleur moment pour acheter et vendre des actions, y compris la période de gel

LC309

arrière-plan

J'ai lutté avec ce sujet pendant longtemps, et après avoir lu beaucoup d'idées de solutions, il y a encore des choses que je n'ai pas expliquées clairement.

Enfin, j'en ai finalement trouvé un qui peut expliquer clairement l'idée (il ne semble pas y avoir de failles) :
les réponses aux autres questions peuvent être correctes, mais certaines explications nécessaires sont omises, ce qui conduit à un manque de compréhension

Ce n'est pas facile

Peut-être que le sujet lui-même n'est pas particulièrement clair. Ajouter ici :

对中间的某一天而言,是否存在除了:买入 / 卖出 / 冷冻期 之外的第四种情况——无操作?
答案是:可以存在。

train de pensée

Parlez ensuite de l'idée de résoudre cette question :
discutez grossièrement selon la situation de [si vous détenez des actions le i-ème jour], puis utilisez la programmation dynamique. L'essentiel est de discuter de la situation et d'être suffisamment clair ! !

Deux contraintes :

  1. Après avoir acheté, vous devez vendre avant de pouvoir continuer à acheter
  2. Vous ne pouvez pas l'acheter immédiatement après l'avoir vendu, et le congeler pendant au moins une journée (vous pouvez aussi le congeler pendant une journée et continuer à ne pas l'acheter, ce qui équivaut à le congeler pendant plusieurs jours !!!)

A discuter par situation

# 步骤1: 考虑第 i 天,总共存在两种状态:持有股票 / 不持有 股票,分别记做 dp[i][0],dp[i][1]。i=0时,对应的利润分别为:-prices[0]、0

dp[i]表示第i天的最大利润,dp[i] = max(dp[i][0],dp[i][1])

# 步骤2: 根据第i天的状态,考虑第 i-1天从什么状态 转换得到 第 i天的状态 
对于 dp[i][0] 再分两种情况:
	1)第i-1天不持有(冷冻期/无操作),注意!!此时第i-2天肯定是不持有,否则要么变成2)的情况重复考虑,要么在i-1天卖出,导致第i天处于冷冻期而无法持有(不能得到dp[i][0]的状态) 
	2)第i-1天持有 【第i-2天可以不持有,也可以不持有】

对于 dp[i][1] 也分两种情况:
	3)第i-1天持有,第i天卖出【第i-2天可以持有,也可以不持有】
	4)第i-1天也不持有,第i天无操作【第i-2天可以持有,也可以不持有】

为什么其他3种情况:2)、3)、4)不考虑第i-2天的情况??
因为其他三种情况对第i-2天没有要求!
合法的状态流转顺序包括:
2)持有/不持有->持有->持有; 
3)持有/不持有->持有->不持有;
4)持有/不持有->不持有->不持有;

唯一不合法的是:持有 -> 不持有 -> 持有 ,对应情况1)!!! 
所以情况1肯定是:不持有->不持有->持有

Les méthodes de transition d'état correspondant aux quatre situations ci-dessus et le profit correspondant au ième jour sont respectivement :

1)dp[i-1][1] -> dp[i][0],dp[i-2][1]-prices[i] # 注意这里需要考虑第i-2天的约束!!而不是 dp[i-1][1]-prices[i]

2)dp[i-1][0] -> dp[i][0],dp[i-1][0]
3)dp[i-1][0] -> dp[i][1],dp[i-1][0]+ prices[i]
4)dp[i-1][1] -> dp[i][1],dp[i-1][1]

le code

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        if n < 2: return 0

        dp = [[0,0] for _ in range(n)]
        # dp[0][0]表示持有,dp[0][1]表示不持有 
        dp[0][0] = -prices[0]
        dp[0][1] = 0
        # 因为下标从2开始,所以需要计算下标为0和1处的初始值,for循环从2到n-1
        # 另一种写法是:数组长度设为n+1,只计算下标为1的初始值,for循环从2到n。减少了初始值计算但是可读性没有前一种强
        dp[1][0] = max(dp[0][1]-prices[1], dp[0][0])
        dp[1][1] = max(dp[0][0]+prices[1], dp[0][1])

        for i in range(2,n): # 注意i-2,需要从2开始循环
            dp[i][0] = max(dp[i-2][1]-prices[i],dp[i-1][0])
            dp[i][1] = max(dp[i-1][0]+prices[i],dp[i-1][1])
        # print(dp)
        return dp[n-1][1]

Résumer

Points clés pour résoudre le problème :

  1. Le jour du milieu peut avoir quatre états : achat, vente, période de gel, pas d'opération, au lieu de trois
  2. Le statut de chaque jour est déterminé uniquement selon les deux situations de maintien et de non-tenue, et il n'y a pas d'autres situations. Parmi eux, la détention comprend intrinsèquement : l'achat, le maintien de la détention (aucune opération) ; la non-détention comprend : la vente, le maintien de la non-détention (aucune opération) et la période de gel. Diviser uniquement selon les deux états susmentionnés simplifie le problème et évite la confusion de pensée causée par la considération de toutes les situations en même temps
  3. En cas de transfert d'état : lorsqu'on considère le transfert d'état du i-1ème jour au i-ème jour, une considération particulière est requise : le cas du transfert d'aucune exploitation le i-1ème jour à une exploitation le i-ème jour, cette situation nécessite le i- 2 jours ne tient pas non plus. Pour les trois autres transferts d'état, il n'y a aucune exigence pour l'état du jour i-2
  4. Lorsque la boucle for récurse l'état, vous devez faire attention au calcul du traitement des limites (à partir du 2ème jour) et de la valeur initiale (le 0ème jour et le 1er jour).
  5. Il ne doit pas avoir lieu le dernier jour, sinon le profit maximum ne peut pas être obtenu

Je suppose que tu aimes

Origine blog.csdn.net/qxqxqzzz/article/details/129964112
conseillé
Classement