https://atcoder.jp/contests/abc303/tasks/abc303_d
Caps LockがOffとOnの2状態でDPします。
// Shift vs. CapsLock #![allow(non_snake_case)] use std::cmp::min; //////////////////// library //////////////////// fn read<T: std::str::FromStr>() -> T { let mut line = String::new(); std::io::stdin().read_line(&mut line).ok(); line.trim().parse().ok().unwrap() } fn read_vec<T: std::str::FromStr>() -> Vec<T> { read::<String>().split_whitespace() .map(|e| e.parse().ok().unwrap()).collect() } //////////////////// process //////////////////// fn read_input() -> (u64, u64, u64, String) { let v = read_vec(); let X = v[0]; let Y = v[1]; let Z = v[2]; let S = read(); (X, Y, Z, S) } fn f(X: u64, Y: u64, Z: u64, S: String) -> u64 { let L = S.len(); let mut v: Vec<(u64, u64)> = (0..L+1).map(|_| (0, 0)).collect(); for (i, c) in S.chars().enumerate() { if c == 'a' { let Off = if i == 0 { X } else { min(v[i].0, v[i].1 + Z) + X }; let On = if i == 0 { Z + Y } else { min(v[i].0 + Z, v[i].1) + Y }; v[i+1] = (Off, On) } else { let Off = if i == 0 { Y } else { min(v[i].0, v[i].1 + Z) + Y }; let On = if i == 0 { Z + X } else { min(v[i].0 + Z, v[i].1) + X }; v[i+1] = (Off, On) } } min(v[L].0, v[L].1) } //////////////////// main //////////////////// fn main() { let (X, Y, Z, S) = read_input(); println!("{}", f(X, Y, Z, S)) }