【LeetCode】動的プログラミング研修(5)

ソード ポインター オファー II 091. 家をペイントする

クリックして表示:家のペイント


n 軒の家があり、各家を赤、青、緑の 3 色のいずれかで塗装できるとします。すべての家を塗装し、隣接する 2 つの家を異なる色にする必要があります。
もちろん、市場で販売されているさまざまな色の塗料の価格が異なるため、さまざまな色で家を塗装する費用も異なります。各家を異なる色で塗装するコストは、nx3 の正の整数行列のコストで表されます。
たとえば、cost[0][0] は家 0 番を赤に塗るコストを表し、cost[1][2] は家 1 番を緑に塗るコストを表します。
すべての家を塗装するための最低コストを計算してください。

例 1:
入力: コスト = [[17,2,17],[16,16,5],[14,3,19]]
出力: 10
説明: 家 0 を青にペイントし、家 1 を緑にペイントし、家番号2は青に塗装しました。
最小コスト: 2 + 5 + 3 = 10。

トピック分析

コスト配列の横軸は住宅番号 N、縦軸は色を表します
住宅ごとに色を選択しますが、隣接する住宅間で同じ色を選択することはできません 最小コストを求める


ここに画像の説明を挿入

隣接する家の間で同じ色を選択することはできないため、ハウス No. 0 が青を選択した後、ハウス No. 1 は青を選択できません。
同様に、ハウス No. 1 が緑を選択した後、ハウス No. 2 は緑を選択できません。
最小コストは 2+ です。 5 +3=10

状態遷移方程式

i の位置に到達すると、添え字が 0 の場合は赤、添え字が 1 の場合は青、添え字が 2 の場合は緑の 3 つの状況があります。

dp[i][0]: 位置 i までペイントするとき、最後の位置が赤でペイントされることを示し、このときの最小コストが
dp[i][1]: 位置 i にペイントするとき、最後の位置が赤になることを示します。青に塗られる 色、現時点での最小コスト
dp[i][2]: 位置 i にペイントするとき、最後の位置は緑、現時点での最小コストで塗られることを意味します



位置 i が赤で塗られている場合、区間 [0,i] の最小コストを見つけたい場合は、隣接する家が同じ色を持つことはできないため、最初に区間 [0,i-1] の最小コストを見つける必要があります。したがって、i-1 の位置は青または緑のみになります。 i-1 の位置が青の場合
、区間 [0,i-1] の最小コストは dp[i-1][1] になります。
位置が緑色の場合、区間 [0,i-1] の最小コストは dp[i-1][2] の最小値であり、位置 i のコストを加えたものが区間 [0,i] のコストになります

状態遷移方程式は次のとおりです。
dp[i][0]= min(dp[i-1][1],dp[i-1][2])+costs[i][0];



位置 i が青で塗られている場合、区間 [0,i] の最小コストを見つけたい場合は、隣接する家は同じ色を取ることができないため、まず区間 [0,i-1] の最小コストを見つける必要があります。したがって、i-1 位置は赤または緑のみになります
。 i-1 位置が赤の場合、[0,i-1] 間隔の最小コストは dp[i-1][0] になります
。が緑色の場合、区間 [0,i-1] の最小コストは
dp[i-1][2] の最小値であり、位置 i のコストを加えたものが区間 [0,i] のコストになります。

状態遷移方程式は次のとおりです。
dp[i][1]= min(dp[i-1][0],dp[i-1][2])+costs[i][1];



位置 i が緑色に塗られている場合、区間 [0,i] の最小コストを見つけたい場合は、隣接する家は同じ色を取ることができないため、最初に区間 [0,i-1] の最小コストを見つける必要があります。i-1 の位置が赤の
場合、[0,i-1] 間隔の最小コストは dp[i-1][0] になります
。位置が緑色の場合、区間 [0,i-1] の最小コストは dp[i-1][1] の最小値であり、位置 i のコストを加えたものが区間 [0,i] のコストになります

状態遷移方程式は次のとおりです。
dp[i][2]= min(dp[i-1][0],dp[i-1][1])+costs[i][2];

完全なコード

class Solution {
    
    
public:
    int minCost(vector<vector<int>>& costs) {
    
    
             
             int n=costs.size();
             //扩列 一行
             // 将 n+1个 vector数组 的3个数 都初始化为0
            vector<vector<int>>dp(n+1,vector<int>(3,0));
            int i=0;
            for(i=1;i<=n;i++)
            {
    
    
                //状态转移方程
                  dp[i][0]=min(dp[i-1][1],dp[i-1][2])+costs[i-1][0];
                  dp[i][1]=min(dp[i-1][0],dp[i-1][2])+costs[i-1][1];
                  dp[i][2]=min(dp[i-1][0],dp[i-1][1])+costs[i-1][2];
            }
            //返回 最后一次粉刷 三种颜色 其中的最小花费
            return min(min(dp[n][0],dp[n][1]),dp[n][2]);
    }
};

初期化
状態遷移方程式を用いて、iが0のときは範囲外アクセスが発生するので、
iが0のとき、つまり0番家の塗装が赤・青・緑になった後、行を展開します。この時の最小コストは
0番ハウスによるものです 一番最初なので最小コストはcosts配列に相当する要素で、
展開した列の全行を0にするだけです。

最後の家を塗装した時点で経費計上されるので、
赤・青・緑の最後の3色を比較した最低コストが最低コストとなります。

309. 株式の売買に最適な時期には凍結期間が含まれる

クリックして表示:株式を売買するのに最適な時期には凍結期間が含まれます


整数配列の 価格 を指定します。ここで、prices[i] は i 日目の株価を表します。
最大利益を計算するアルゴリズムを設計します 次の制約の下では、できるだけ多くのトランザクション (株式の売買を複数回行う) を完了できます。 株式を売却した
後、翌日には株式を購入することはできません (つまり、凍結期間は 1 日です)。
注: 同時に複数の取引に参加することはできません (再度購入する前に、前の株式を売却する必要があります)。

例 1:
入力: 価格 = [1,2,3,0,2]
出力: 3
説明: 対応する取引ステータス: [買い、売り、凍結期間、買い、売り]
例 2:
入力: 価格 = [1 ]
出力: 0

トピック分析

株を買って売ると凍結期間に入り何もできなくなる
最終的に上記の最大利益は3

状態遷移方程式

dp[i]:i日目終了時に得られる最大利益を表す
iの位置には株を保有する、株を売り続けるの4つの状態がある 凍結期間中に株を売却すると
保有状態を表す添字 0 の株、添字 1 は株の売却ステータスを示すために使用され、添字 2 は株の売却ステータスを示すために使用され、添字 3 は凍結期間、つまり dp を示すために使用されます
。 [i][0] 保有株 dp[i][1] 売却継続 dp[i][2] 売却株 dp[i][3] 凍結期間

dp[i][0]:i日目終了後、株を保有している状態であることを示し、その時点での最大利益 dp[i][1]:i日目終了後であることを
示すi日目は株を売り続けている状態 この時の最大利益
dp[i][2]:i日目終了後も株を売り続けている状態を示す、このときの最大利益
dp[i][3]: i 日目終了後は凍結期間の状態であることを示します。

凍結期間前に株を売却し、何もしなければ凍結期間後も株を売り続ける

在庫を保持する

i-1日が株式を保有している状態であれば、i日もi-1日の状態を継続します
この場合、dp[i][0]=dp[i-1][0]


i-1日目を凍結期間とすると、i日目は株を買っている状態
i-1日目からi日目まで株価を差し引く必要がある
この場合:dp[i] [0]=dp[i -1][3]-価格[i]


凍結期間終了後から i-1 日目までは株を売る状態を維持し、i 日目は株を買う状態 この場合、
dp [i][0]=dp[ i-1][1] -価格[i]


3 つの最大値を取るための状態遷移方程式は次
のとおりです。
dp[i][0]= max ( max(dp[i-1][0],dp[i-1][3]-price[i] ) ,dp [i-1][1]-価格[i]);

株を売り続ける

i 日目に株を売り続けたい場合は、i-1 日目にも株を売り続けることができます。
この場合: dp[i][1]= dp[i-1][1]


i 日目に株を売りたい場合は、i-1 日目を凍結状態にすることができます。
この場合: dp[i][1]=dp[i-1][3]


2 つの状態遷移方程式の最大値を取得します。 dp[i][1]=max(dp[i-1][1],dp[i-1][3]);

在庫を売る

i-1 日目に株式を保有し、i 日目に株式を売却します
。 i-1 日目から i 日目まで、株価を加算する必要があります。

状態遷移方程式は次のとおりです。
dp[i][2]= dp[i-1][0]+price[i];

凍結期間

i-1日目の株式売却の様子、i日目の凍結期間の様子

状態遷移方程式は次のとおりです。
dp[i][3] = dp[i-1][2];

完全なコード

class Solution {
    
    
public:
    int maxProfit(vector<int>& prices) {
    
    
     int n=prices.size();
     int i=0;
     vector<vector<int>>dp(n,vector<int>(4,0));
     //将股票买了,需要花钱 所以利润为负
     dp[0][0]=-prices[0];
     for(i=1;i<n;i++)
     {
    
    
         //持有股票
         dp[i][0]= max( max(dp[i-1][0],dp[i-1][3]-prices[i]),
         dp[i-1][1]-prices[i]);

         //保持卖出股票
         dp[i][1]= max(dp[i-1][1],dp[i-1][3]);

         //卖出股票
         dp[i][2]=dp[i-1][0]+prices[i];

         //冷冻期
         dp[i][3]= dp[i-1][2];
     }
     //最后一天 若买入 则不会获得最大利润 ,所以去除下标为0的情况
     return max(max(dp[n-1][1],dp[n-1][2]),dp[n-1][3]);
    }
};

714. 株式の売買に最適な時期には手数料が含まれます

クリックして表示:株式の売買に最適な時期には手数料が含まれます


整数配列のpricesを指定すると、price[i]はi日目の株価を表し、整数の手数料は株式取引の手数料を表します。
取引は無制限に完了できますが、取引ごとに取引手数料を支払う必要があります。すでに株を購入している場合は、売却するまで別の株を購入し続けることはできません。
利益の最大値を返します。
注: ここでの取引とは、株式の購入、保有、売却のプロセス全体を指し、各取引ごとに手数料のみを支払う必要があります。

例 1:
入力: 価格 = [1, 3, 2, 8, 4, 9]、手数料 = 2
出力: 8
説明: 達成できる最大利益:
ここで買う 価格[0] = 1
ここで売る 売る価格[ 3] = 8
ここで買う価格[4] = 4
ここで売る価格[5] = 9
合計利益: ((8 - 1) - 2) + ((9 - 4) - 2 ) = 8

トピック分析

配列要素の値が1の場合、配列要素の値が3または2のときに株を買うのは不経済です。配列要素の値が8の場合、株を売ります、8-1-2=
5
配列要素の値が 4 の場合は株を買い、配列要素の値が 9 の場合は株を売ります。 9-4-2=3 最大
利益は 5+3= 8 です。

状態遷移方程式

dp[i]: i 日目終了後に得られる最大利益を示します。


位置 i には、買い状態と売り状態の 2 つの状態があります。

f[i]: i 日目終了後、買いの状態であることを示し、その時点での最大利益 g[i]: i 日目終了後、買いの状態であることを
示す売り状態であり、現時点での最大利益


株式売却時に手数料が加算される場合を想定し、手数料の支払いは1回のみとなります

f[i] 状態遷移方程式

i-1 日が買い状態で、i 日目が何もしなかった場合、i 日も買い状態になります。この場合:
f [i]=f[i-1]


i-1 日が売り状態であれば、i 日目は買い状態となるため、
株式の購入に相当する価格 [i] を差し引く必要があります。
この場合、f[i] =g[i-1]-価格[i ]

状態遷移方程式は次のとおりです。
f[i] =max(f[i-1],g[i-1]-price[i]);

g[i] 状態遷移方程式

i-1 日に状態が売却され、i 日に何も行われなかった場合、i 日目も売却状態になります。この場合
: g[i]=g[i-1]


i-1日目が買い状態であれば、i日目は売り状態となり、
売却に相当する利益価格[i]を加算する必要があり、同時に手数料がかかります。株式を売却するために必要な
この場合: g[i]=f [i-1]+price[i]-fee

状態遷移方程式は次のとおりです。
g[i]= max(g[i-1],f[i-1]+price[i]-fee);

完全なコード

class Solution {
    
    
public:
    int maxProfit(vector<int>& prices, int fee) {
    
    
        int n=prices.size();
        int i=0;
        //f表示 买入  g表示卖出
        vector<int>f(n,0);
        vector<int>g(n,0);
        //将股票买了,需要花钱,所以利润为负
        f[0]=-prices[0];
        g[0]=0;
        for(i=1;i<n;i++)
        {
    
    
            f[i]=max(f[i-1],g[i-1]-prices[i]);
            g[i]=max(g[i-1],f[i-1]+prices[i]-fee);
        }
        //在最后一个位置处  在买股票对应的利润肯定是没有将股票卖出的利润多的
        return g[n-1];
    }
};

おすすめ

転載: blog.csdn.net/qq_62939852/article/details/131423882