問題文
問題
博士パテルはあり N プレートのスタックを。各スタックには含ま Kの プレート。各プレートは、正の持つ 美しさの値を、それがどのように見えるか美しい記述する。
博士パテルは正確に利用したいと思います Pの 夕食のために今夜を使用するためにプレートを。彼は、スタックにプレートを取るしたい場合、彼はまた、同様にそのスタックでそれ以上のプレートのすべてを取る必要があります。
ヘルプ博士パテルは、ピックアップ Pの 美しさの値の総和を最大にするプレートを。
入力
入力の最初の行は、テストケースの数、得られる Tを。 Tの テストケースは以下の通り。各テストケースは三つの整数を含む行から始まる N、 K および Pを。その後、 Nの 行が続きます。i番目の行が含まれている Kの 上から下へのプレートの各スタックの美しさの値を記述する整数を、。
出力
各テストケースのために、出力1行を含む Case #x: y
場合、 x
(1から始まる)テストケースの数であり、 y
博士パテルが選ぶことができること美値の最大値の総和です。
制限
制限時間:テスト・セットあたり20秒。
メモリ制限:1ギガバイト
1≤ T ≤100。
1≤ K ≤30。
1≤ P ≤ N * K。
美しさの値は、1と100の間で含まれています。
テストセット1
1≤ N ≤3。
テストセット2
1≤ N ≤50。
サンプル
入力
|
出力
|
2 2 4 5 10 10 100 30 80 50 10 50 3 2 3 80 80 15 50 20 10 |
ケース#1:250 ケース#2:180 |
サンプルケース#1では、博士パテルが選択する必要が P = 5枚のプレート:
- 彼は、第一のスタック(10 + 10 + 100 = 120)からのトップ3のプレートを選ぶことができます。
- 彼は、第二のスタック(80 + 50 = 130)から、トッププレート2を選ぶことができます。
合計では、美しさの値の合計は250です。
サンプルケース#2では、博士パテルが選択する必要があります P = 3枚のプレート:
- 彼は、第一のスタック(80 + 80 = 160)から、トッププレート2を選ぶことができます。
- 彼は、第二のスタックから何のプレートを選ぶことはできません。
- 彼は、第三のスタック(20)から上部プレートを選ぶことができます。
合計では、美しさの値の合計は180です。
注: 以前の版とは異なり、キックスタート2020年には、すべてのテスト・セットは、あなたが提出時に瞬時にフィードバックを受ける意味、目に見える評決テスト・セットです。
問題のリンク
ビデオチュートリアル
あなたはここに詳細なビデオチュートリアルを見つけることができます
思考プロセス
最初に考えたのは、これがリストから作業がソートされていないではないだろうと我々は順を追って制約にソートすることはできません、複数のリストをマージに似ています。
考え直し、リスト内のすべてのトップの要素から最大値をマージし、常に最大ヒープを維持し、かつあります。貪欲な意志はここで働いていないので、これは間違っています。例えば、以下の我々は1、2、2 2を選択します最大ヒープを使用して、代わりに1、3枚のプレートを選択したい場合は、100
2、2、2、2、2
1、1、100、100、100
第三の思考はPのすべてのコンボのために、強引に私たちが持っているようだ、私たちは、最大値が何を確認してください。分析からの引用、それの指数時間の複雑さ
例えば、もし Nが = 3との任意の値の K および P 、すべての可能なトリプル(S生成1 、S 2 、S 3 )は、Sつまり1 + S 2 + S 3 = P 0≤S I ≤ Kを。注:S iは i番目のスタックから取り出さプレートの数です。
これは再帰を介して行うことができ、合計時間複雑度は、Oである(K N期限を遵守します)。
これを最適化するために記載及び最終溶液は、動的プログラミングを使用しています。これは、これらのコーディング大会では非常に一般的です。
分析からの引用
まず、聞かせてのは、中間状態の考える 私たちは、合計でjのプレートを選択する必要がある場合に最初のiスタックを使用して取得することができる最大の和を表し、DP [i]の[j]を。
次に、反復スタックオーバーとは、質問に答えるために試してみてください。 私たちが使用して、合計でjのプレートを選択しなければならなかった場合は、最大の合計は何である私は、我々がこれまで見てきたスタック? これは、[i]の[j]をごDP与えるだろう。しかし、我々は、また、決定する必要があり 、これらのJプレートの中で、どのように多くは、i番目のスタックから来ますか? すなわち、レッツは、その後、我々はi番目のスタックからのx、プレートを選ぶと言う [i]はDP [J] = MAX(DP [I] [J]、合計[I] [X] + DP [I-1] [JX ]) 。したがって、iがスタックから合計Jプレートを選択するために、我々は、i番目のスタックと[J、J-1、...、0からどこ[0、1、...、j]はプレート間選ぶことができます]は、それぞれ前のI-1スタックからプレート。また、我々は1≤のすべての値のためにこれを行うために必要な J ≤ P。
流れは次のようになります。
iについて[1、 N ]:
jに対して[0、 P ]:
DP [I] [J]:= 0
xの[0、分(J、 K)]:
DP [I] [J] = MAX(DP [I]、[J]、和[I] [X] + DP [I-1] [JX])
我々は密接に観察した場合、これはと似て 0-1ナップザック問題 いくつかの追加の複雑さを持ちます。締結し、全体的な時間計算量はO(なりN * P * K)。
ソリューション
1つの 公共 静的 ボイドメイン(文字列[]引数){ 2 スキャナーS = 新しいスキャナ(新しい BufferedReaderの(新しいInputStreamReaderの(System.in)))。 3つの 4 INTテストケース= s.nextInt()。 5 INT caseNum = 1 。 6枚の プレートプレート= 新しいプレート()。 7 8 しばらく(caseNum <= テストケース){ 9 INT N = s.nextInt()。 10 int型 K = s.nextInt()。 11 int型のp =s.nextInt(); 12 13 のint [] []の値= 新しい INT [N] [K]。 14 のために(INT I 0 =;私は<N; I ++ ){ 15 のために(INT J = 0; jが<kであり、j ++ ){ 16の 値[I] [J] = s.nextInt()。 17 } 18 } 19 20 のSystem.out.println(String.Formatの( "ケース#1%のD:%のD" 、caseNum、plates.maxPlatesBeautyValue(値、P)))。 21 caseNum ++ ; 22 } 23 } 24 25 プライベート INT maxPlatesBeautyValue(INT [] []の値、int型のnumberOfPlates){ 26 INT N = values.length。 27 のint、K =値[0 ] .LENGTH。 28 int型のp = numberOfPlates。 29 30 31 // 一次元アレイ使用することができる 32 INTを [] [] prefixSum = 新しい INT [N + 1] [K + 1 ]。 33 INT [] []、ルックアップ= 新しい INT [N + 1] [P + 1 ]。 34 35 のために(INTI = 1; I <= N。I ++ ){ 36 のために(INT J = 1; J <= kであり、j ++ ){ 37 prefixSum [I] [J] = prefixSum [I]、[J - 1] +値[I - 1] [J - 1 ]。 38 } 39 } 40 41 のために(INTは、 I 1 =、iが<= N; I ++ ){ 42 のために(INT J = 1; J <= P; J ++ ){ 43 参照[I] [J] = 0 ; 44 45 のために(INT ; X <= Math.min(j、k)は、X = 0のx ++ ){ 46 検索[I] [J] = Math.max(参照[I]、[J]、prefixSum [I] [X] +ルックアップ[I - 1] [J - X])。 47 } 48 } 49 } 50 51 戻り参照[n]が[P]。 52 }
DPソリューション
時間複雑:O(N * P * K)
スペース複雑さ:O(N * MAX(P、K))