Googleのキックスタート2020ラウンドA:プレートソリューション

問題文 

問題

博士パテルはあり  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))

 

リファレンス

おすすめ

転載: www.cnblogs.com/baozitraining/p/12596326.html