質問の意味:
この場所は時間の時間単位の日を、Vovaは睡眠睡眠睡眠n回に行きます
少なくとも1時間の単位が、マスト睡眠 - 各床は、時間又は[I]の[i]の単位を眠ることができ
あなたは時間に目を覚ます場合は、[L、R]この範囲内で、その後、スリープまでの時間は十分に(解答1)
(再び私は......目覚めた直後に眠っている感じ)
Vovaは良い睡眠の最も多数を作るために睡眠にn回を配置する方法を尋ね
(すなわち、各時間が加算[I]又は[I] - 1とモジュロ時間、回数LとRとの間の落下時)
問題解決のアイデア:
ダイナミックプログラミング、2次元配列は、i番目の睡眠への記録層は、i番目の時間別のレコードを覚まします
DP [I] [J]私は番目の時間、睡眠のi番目の最大値は、完成睡眠を持っている意味と睡眠を目覚めは、プロセスの答え、jは
時間は0から始まるので、-1に配列を初期化し、特別な治療DP [0] [0] = 0
I = 1〜N J = 0〜H-1
私はi番目の睡眠を表し、jはi番目がスリープ状態に始まった時間を表し
限りDP [I-1] [j]のよう!= -1、状態遷移を行うことができる(に等しい-1 jを介して到着の処理時間に相当するものがないので)
仮定すると、この二次睡眠単位時間t
状態遷移方程式
DP [i]は[T] = MAX(DP [I] [T]、DP [I-1]〜[J] +(T> = L && T <= R 1:0))
表し就寝時はjがあるとき、i番目の目を覚ますには、i番目の答えで眠っている、Tの最大値の時間に目を覚ますと、自分から転送されたいずれか大きい方
(46ms / 2000ミリ秒)
1つの#include <ビット/ STDC ++ H.>
2 使用して 名前空間STD;
3 INT DP [ 2050 ] [ 2050 ];
4 int型のmain()
5。 {
6。 IOSの:: sync_with_stdio(0 );
7 cin.tie(0); COUT .tie(0 );
8。 のmemset(DP、 - 1、はsizeof DP); // 初期、時間が訪問-1設定されていない
9。 DP [ 0 ] [ 0 ] = 0 ; // 一定時間がある場合訪問され、その後、DPの質問の最大数を満たすことを目的として、このプロセスの到着時間を表し、
10 INT 、N、H、L、R、I、J、T。
11 CIN >> N >> H >> L >> R。
12 のためには、(iは= 1 ; I <= N; I ++ )
13 {
14 CIN >> 。
15 のための(j = 0 ; J <H、J ++)// 每种时间都考虑一遍
16 {
17 であれば(DP [I- 1!] [J] = - 1 )
18 {
19 、T =(J +) %H;
20 DP [i]は[T] = MAX(DP [I] [T]、DP [I- 1 ] [J] +(T> = L && T <= R?1:0)); // その1 + DPの条件を満たす次の位置場合。
21が T =(J + A- 1。 + H)%のH; // 両方のケースは、i番目に考慮すべき
22である DP [i]と[T = MAX(DP [I] [T]、DP [I- 1 ] [J] +(T> = L && T <= R&LT?1:0 ));
23である }
24 }
25 }
26は、 INT ANS = DP [N- ] [ 0 ];
27 のために(私は= 1。 ; I <H、I ++ )
28 ANS = MAX(ANS、DP [N-] [I]); //は最後の終了後に最大値時刻を見つける
29 COUT ANS << << ' \ N- ';
30
31 戻り 0 ;
32 }