彗星OJ - コンテスト#11 B- usiness

オリジナルタイトルリンク

質問の意味:

n日前、投資プログラムのM種類、および[X] K F以下の補助金残高があります。

あなたが投資プログラムの数は無制限に投資することを選択することができます毎日(ただし、そのバランスが0以上であることを確認するため)、投資収益は、n日間返品の終了後になります。

投資の最大のリターンを求めていることはどのくらいです。

アイデア:

この投資のお金が、その後、最後の収穫は、完全なナップザック問題に変換することができます。多様な毎日のバランスの状態はとても毎日が始まるので、ステートに移行しなければなりません。

i日のために提供DP [I] [J]、バランスJ。次に、状態遷移は毎日開始:DP = MAX(DP [I] [J + F [J]、DP [I-1]〜[J])[I] [J] F jは+]; // F [ j]は、補助金の関数であり、

その後、同じ日に完全にバックパックに転送

コード:(他のコードのコメントを参照してください)

#include <iostreamの> 
する#include <cstdioを> 
する#include <CStringの>
 使用して 名前空間STD;
 CONST  INT INF = 0x3f3f3f3f ; 
 INT F [ 2050 ]; // (0 <= K <= 1000)、(K + F [K] <= 2000)
のint V [ 110 ]、W [ 110 ]; // 。(1 <= M <= 100)
INT DP [ 105 ] [ 3005 ]; // MAX(Iは+ F [I])
INT メイン() {
     int型N-、M、K; 
    CIN >> M >> N- K;
     // 曜針残金最大に
    INTMmaxの= 0 ; 
    以下のためにint型 i = 0 ; iは= Kを<I ++は{)
        のscanf(" %dの"、&F [i])とします。
        Mmaxを = MAX(Mmaxを、F [i]が+ I)。
    } 
    のためにint型 I = 1 ; I <= M; iは++ ){ 
        scanf関数(" %d個の%のD "、&​​V [i]は、&W [I])。
    } 
    のmemset(DP、 -INF、はsizeof (DP))。
    DP [ 1 ] [ 0 ] = 0 以下のためのint型L = 2、L <= N; L ++ ){
         ためのint型 J = 0 ; J <= kであり、j ++ 
            DP [L] [J + F [J] = MAX(DP [L] [J + F [ J]、DP [1- 1 ] [J])。
        以下のためにint型 I = 1 ; I <= M; iは++ ){
             ためINT J = Mmaxを-V族[i]は、J> = 0 ; j-- ){ 
                DP [L] [J] = MAX(DP [L ] [J]、DP [L] [J + V [i]は] + [I])W。
            } 
        } 
    } 
    // 最后一天状态更新
    INT ANS = 0 以下のためのint型 i = 0 ; iは= Mmaxをを<; iは++ ){ 
        ANS = MAX(ANS、DP [n]は[I] + iは+ Fを[I])。
    } 
    COUT << ANS << ENDL。
}

 

おすすめ

転載: www.cnblogs.com/Tianwell/p/11580934.html