問題の意味: - 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 ; }