あるエンジニアのAtCoder奮闘記

東京都港区にあるアミフィアブル株式会社のエンジニアが、AtCoderで解いた問題について振り返ったりしていく会社公認のブログです。

AtCoder ABC140 C - Maximal Value (Go)

irisruneです。台風の影響により、今週は火・水・金の投稿となります。

問題

https://atcoder.jp/contests/abc140/tasks/abc140_c

B_iからA_iを逆算するにはどうすればいいかという問題です。

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
)

var sc *bufio.Scanner

func nextInt() int {
    sc.Scan()
    i, e := strconv.Atoi(sc.Text())
    if e != nil {
        panic(e)
    }
    return i
}

func minInt(a, b int) int {
    if a < b {
        return a
    }
    return b
}

func main() {
    sc = bufio.NewScanner(os.Stdin)
    sc.Split(bufio.ScanWords)
    n := nextInt()

    ans := 0
    bPrev := -1
    for i := 0; i < n-1; i++ {
        b := nextInt()
        switch {
        case i == 0:
            ans += b
        default:
            ans += minInt(b, bPrev)
        }
        bPrev = b
    }

    fmt.Println(ans + bPrev)
}

A_iからB_iを求める方法として、問題文でB_i\geq\max(A_i,A_{i+1})が示されています。逆にB_iからA_iを求める方法を考えると、A_i\leq\min(B_{i-1},B_i)となることがわかります。

ここから不等号を等号に置き換えるだけでA_iの最大値を求められますが、A_i(1\leq i\leq N)に対してB_i(1\leq i\leq N-1)であるため、A_0,A_Nについては求め方が異なることに注意が必要です。具体的にはA_0\leq B_1,A_N\leq B_nと置き換える必要があります。

なお、B_{-1},B_N=\inf(\geq 10^5)とおいてB_iの数列の両端に追加すると、A_0,A_nについても他のA_iと同様に求めることができるためコードがより簡潔になります。

雑記

  • 今週は水曜日にABC140-D、金曜日にARC059-E(部分点+満点)を投稿予定です。