教育改革(CodeForces-119C)[DP]

 

問題の意味: - XI-1 * K Mをインクリメントすることが困難なコースのn n日、1日、に排出から選択され、各コースのジョブに対応するには西、およびXI = XI-1 + Kまたは西の量仕事の総量はできるだけ大きくし、及び配置は、配置ならば、スキームを求めているかどうかを尋ねました。

アイデア:DFS検索でゲームを襲撃しようとする試みが、残念ながら時間外、ゲームは解釈が、これはDPであることを知っているに見えた後、成功せず、最適化の様々な試みるが、また、被写体がDPは、多くの時間を節約するかどうとき、多くの検索ソリューションを使用することができることを見出し!

  DPは、三次元アレイ、DP [I] [J] [k]を確立し、iがi番目の日表し、jはi番目の行、j番目の日のコースを表し、kは端部を残した第ジョブJコースとして選択されたジョブの量を表しますポイント+ K。プレ配列が確立されなければならない場合DPパスをマークすることに留意されたいです。

コードは以下の通りであります:

#include <iostreamの> 
する#include <アルゴリズム> 
の#include <CStringの> 
する#include <ベクトル>
 使用して 名前空間STDを、

構造体の主題{
     長い 長い、B。
    int型のC、ID;
    ブール 演算子 <(被写体&T){
         戻り C < TC。
    } 
} [ARR 60 ]。
構造体のルート{
     int型のほか、ID。
    ルート(){} 
    経路(int型のx、int型のY)、ID(X)、また(Y){} 
}事前[ 60 ] [ 60] [ 120 ]、終了します。

INTのN、M、K。
長い 長い DP [ 60 ] [ 60 ] [ 120 ]。// 日/ NUM /ワーク

BOOL makeDp(){ 
    memsetの(DP、 - 1はsizeof (DP))。
    INT J = 1 ; J <= Mであり、j ++ のための長い 長い I =のARR [J] .A; I <= ARR [J] .B; iは++ ){ 
            DP [ 1 ] [J] [I- ARR [J] .A] = I。
        } 
    のためのINT I = 1; iがN <; Iは++ ){
         ためint型 J =であり; J <= M && M-J> = NI; J ++ ){
             ため長い 長い KK =のARR [J] .A; KK <= ARR [J] .B ; KK ++ ){
                 場合(DP [I] [J] [KK-ARR [J] .A] == - 1 続けますint型 JJ = J + 1 ; JJ <= M; JJ ++ ){
                     場合(ARR [JJ] .C == ARR [J] .C)
                         続けますもし(K * KK> = ARR [JJ] .A && K * KK <= ARR [JJ] .B){
                         もし(DP [iが+ 1 ] [JJ] [K * KK-ARR [JJ] .A <DP [I] [J] [KK-ARR [J] .A] + Kの*のKK){ 
                            DP [I + 1 ] [JJ] [K * KK-ARR [JJ] .A] = DP [I] [J] [KK-ARR [J] .A] + Kの*のKK。
                            事前[I + 1 ] [JJ] [K * KK-ARR [JJ] .A] =ルート(J、kk- ARR [J] .A)。
                        } 
                    } 
                    もし(K + KK> = ARR [JJ] .A && K + KK <= ARR [JJ] .B){
                         場合(DP [I + 1 ] [JJ] [K + KK-ARR [JJ] .A < DP [I] [J] [KK-ARR [J] .A] + K + KK){ 
                            DP [I + 1 ] [JJ] [K + KK-ARR [JJ] .A] = DP [I] [J ] [KK-ARR [J] .A] + K + KK。
                            事前[I + 1 ] [JJ] [K + KK-ARR [JJ] .A] =ルート(J、kk- ARR [J] .A)。
                        } 
                    } 
                } 
            }    
        } 
    } 
    長い フラグ= - 1 以下のためにint型 I = N; I <= M; iは++ ){
         ための長い  jは=のARR [I] .A; J <= ARR [I] .B; J ++ ){
             場合(フラグ<DP [n]は[ I] [J- ARR [I] .A]){ 
                フラグ = DP [n]は[I] [J- ARR [I] .A]。
                終了 =ルート(I、J-ARR [I] .A)。
            } 
        } 
    } 
    場合(フラグ=! - 1 を返す 返す ; 
} 

ボイド findAns(ブールX){
     場合(!X)
        COUT << " NO " 他の{ 
        裁判所未満 << " YES \ N " ; 
        ベクター <ルート> ANS。
        ルートヘクタール = 終わります。
        以下のためにint型 I = N; I> =1 ; i-- ){ 
            ans.push_back(HA)。
            HA = あらかじめ[I] [ha.id] [ha.addition]。
        } 
        のためにint型 I = N- 1、I> = 0 ; i-- ){ 
            COUT << ARR [ANS [I] .ID] .ID << "  " << ARR [ANS [I] .ID]。 + ANS [i]は.addition << ENDL。
        } 
    } 
} 

int型のmain(){ 
    CIN >> N >> M >> K。
    以下のためにint型 i = 1 ; iが<= M; iは++ ){ 
        CIN >> ARR [I] .A >> ARR [i]は.B >>
        ARR [I] .ID= I; 
    } 
    ソート(ARR + 1、ARR + 1 + M)。
    findAns(makeDp())。
    リターン 0 ; 
}
xxmlalaにより、

おすすめ

転載: www.cnblogs.com/xxmlala-fff/p/11617239.html