ワインのライン

行のNのワインがあります。毎年あなたは左端または右端のワインのいずれかを販売しています。i番目のワインは、k番目の年に最初の価格P [i]と価格のk * pを[I]を持っています。可能な最大総利益は何ですか?

 

ソリューション1.ボトムアップ動的計画

状態:
DP [I] [J]:今年のワイン[I、J]の最大の可能な利益I - 0 + N - 1 - J + 1 = N + I - jは
DPの[I] [J] =最大{P [I] *(N + I - J)+ DP [I + 1] [J]、P [J] *(N + iは-j)+ DP [I]、[J - 1]}

初期化:
DP [i]は[I] = N * P [i]の

答え:
DP [0] [N - 1]

 

iとjをループ。この場合、ループの順序が重要です。最初 - DP [i]の[j]を計算するために、我々は、DP [I + 1] [J]とDP [i]が[1 j]を持っている必要があります。NにI + 1から昇順で1 0とjに - - これは、私たちは私がNから順にループする必要があることを意味1。

    公共 INT maxProfitBottomUp(INT [] P){
         int型 N = p.length。
        INT [] [] DP = 新しい INT [N]、[N]。
        int型 ; iがNを<I ++は、I = 0 {)
            DP [i]は[I] = N * P [i]は、
        } 
        のためのint型 I = N - 1; I> = 0; i-- ){
             ためint型、J <N; J ++ J = I + 1 ){ 
                DP [I] [J] = Math.max(P [ I] *(N + I - J)+ DP [I + 1] [J]、P [J] *(N + iは-j)+ DP [I]、[J - 1 ])。
            }
        }
        リターンDP [0] [N - 1 ]。
    }

 

最初の間隔の長さにわたってループ、すべての可能な左スタートオーバー、ループ。

    公共 INT maxProfitBottomUp(INT [] P){
         int型 N = p.length。
        INT [] [] DP = 新しい INT [N]、[N]。
        int型 ; iがNを<I ++は、I = 0 {)
            DP [i]は[I] = N * P [i]は、
        } 
        のためのINT LEN = 2; LEN <= N; LEN ++ ){
             ためのint型、L = 0; L <= N - LEN; L ++ ){
                 int型、R = L + LEN - 1 INT Y = N + L - R。
                DP [L] [R]= Math.max(P [L] * Y + DP [L + 1] [R]、P [R] * Y + DP [L] [R - 1 ])。
            } 
        } 
        戻り DP [0] [N - 1 ]。
    }

 

 

ソリューションII。動的なプログラミングをトップダウン

状態:

DP [L] [R]:最大の可能な利益我々は[L、R]をインターバルに行く前に。

DP [L] [R] = Math.max(DP [L] [R + 1] + P [R + 1] *(カレー - 1)、DP [1 - 1] [R] + P [1 - 1 ] *(カレー - 1))、カレー= N + L - R。


初期化:
DP [0] [N - 1] = 0


答え:
の最大{DP [I] [I] + P [I] * N}

 

    公共 INT maxProfitTopDown(INT [] P){
         int型 N = p.length。
        INT [] [] DP = 新しい INT [N]、[N]。
        DP [ 0] [N - 1] = 0 

        INT - ; LEN> = 1 len-- 1 LEN = N {)
             のためのint型 L = 0、L + LEN <= N; L ++ ){
                 int型 R = L + LEN - 1 INTカレー= N + L - R。
                もし(R <N - 1 ){ 
                    DP [L] [R]= Math.max(DP [L] [R]、DP [L] [R + 1] + P [R + 1] *(カレー- 1 ))。
                } 
                場合(L> 0 ){ 
                    DP [L] [R] = Math.max(DP [L] [R]、DP [1 - 1] [R] + P [1 - 1] *(カレー- 1 ) ); 
                } 
            } 
        } 

        int型 RES = 0 以下のためにint型 I 0 =; iがNを<; Iは++ ){ 
            RES = Math.max(RES、DP [i]は[I] + P [I] * N)。
        } 
        戻りRESと、
    }

 

 

ソリューションIII。接頭和とボトムアップ動的計画 

主なアイデア:私たちが想定した場合、すべての間隔は1年で始まり、すでに間隔の最大の利益を持っている[R、Lを - 1]と[L + 1、R]、その後、区間[L、R]を計算するために、我々はすべてのシフト[L、R - 1]のため年1によると[L + 1、r]は、次いで、いずれかのP [R]またはp [L]を加えます。これは、区間[L、R]のprefixsumあります。

 

DP [L] [R]:ワインの最大の可能な利益[L、R]年1から始まる
DP [L] [R] = Math.max(DP [L] [R - 1]、DP [L + 1] [R])+ prefixSum [L、R]

INIT:DP [i]は[I] = 1 *のP [I]

回答:DP [0] [N - 1]

    公共 INT maxProfitPrefixSum(INT [] P){
         int型 N = p.length。
        INT [] [] DP = 新しい INT [N]、[N]。
        以下のためにint型 I 0 =; iがNを<; Iは++ ){ 
            DP [i]は[I] = P [i]は、
        } 
        INT [] prefixSum = 新しい INT [N]。
        prefixSumは、[ 0]、P [= 0 ]。
        int型、iがNを<; I 1 = I ++は){ 
            prefixSum [I] = prefixSum [I - 1] + P [i]は、
        } 
        のためにint型 I = N - 1; I> = 0; i-- ){
             ためのint型 J = I + 1、J <N; J ++ ){ 
                DP [I] [J] = Math.max(DP [I] [J - 1]、DP [I + 1] [J])+ prefixSum [J] - (I> 0 prefixSum [I - 1]:0 )。
            } 
        } 
        戻り DP [0] [N - 1 ]。
    }

 

おすすめ

転載: www.cnblogs.com/lz87/p/11518228.html