[topic] 情報オリンピック2007年度世界大会「坑夫」

中高生向けの情報オリンピックの世界大会2007年度の第2日目「坑夫」です。コンテストは2日間にて行われます。クロアチアにて開催されました。

「問題ごとに、プログラムの実行時間(や使用メモリ量)に制限が設定されています。」にご注意ください。本問では、制限時間1.5秒、メモリ制限16MBとなっています。

入出力は標準入出力にて行います。

採点は、テストデータにおいて正しい結果が返ってくるかで採点されます。出題時はテストデータの一部のみが公開されており、全てのデータは出題時には公開されていません。

Posted feedbacks - Flatten

Nested Hidden
疑似コート、動的計画法の漸化式は以下の通りです。

-------------------------------------------------

動的計画法の漸化式
  list1(i) = i -> i-iまでに炭坑1に届いた最後の品物2つ 1+3+9通り
  list2(i) = i -> i-iまでに炭坑2に届いた最後の品物2つ
  sum(i, list1(i), list2(i)) = i~N-1の石炭の合計量の最大値
  漸化式
    sum(i, list1(i), list2(i)) = 
      max(
        sum(i + 1, list1(i) :: goods(i), list2(i)) + value(goods(i), list1(i)),
        sum(i + 1, list1(i), list2(i) :: goods(i)) + value(goods(i), list2(i)))
    sum(N, any, any) = 0
  求める物 = sum(0, [], [])

-------------------------------------------------

擬似コード
  i <- (N-1) to 1
    l1 <- 13パターン
      l2 <- 13パターン
        sum(i, l1, l2) を更新

-------------------------------------------------
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
object Miners extends Application {
  val N = readInt
  val foods = new Array[byte](N)
  for(i <- 0 until N) {
    def toNum(v:int):byte = {
      if(v == 'M') 1
      else if(v == 'F') 2
      else if(v == 'B') 3
      else error("ありえない")
    }
    foods(i) = toNum(System.in.read)
  }
  
  var sum = new Array[int](256)
  var sumNext = new Array[int](256)
  val kouho = List(0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15)
  for(i <- (0 until N).reverse) {
    val f = foods(i)
    for(l1 <- kouho) {
      for(l2 <- kouho) {
        def value(f:int, prev:int):int = {
          val p1 = prev % 4
          val p2 = prev / 4
          if(p1 == 0 && p2 == 0) {
            return 1
          } else if(p2 == 0) {
            if(p1 == f) return 1
            else return 2
          } else {
            //println("p1 = " + p1 + ", p2 = " + p2 + ", f = " + f)
            if(p1 == p2 && p2 == f) return 1
            else if(p1 != p2 && p2 != f && p1 != f) return 3
            else return 2
          }
        }
        val v1 = sum(((l1 % 4)*4 + f) * 16 + l2) + value(f, l1)
        val v2 = sum(l1 * 16 + ((l2 % 4)*4 + f)) + value(f, l2)
        sumNext(l1 * 16 + l2) = Math.max(v1, v2)
      }
    }
    val temp = sum
    sum = sumNext
    sumNext = temp
    //println(sum.toList)
  }
  println(sum(0))
}

Index

Feed

Other

Link

Pathtraq

loading...