2023-07-06 bbn 0.37.0 をつくった / 的あて (第五回 アルゴリズム実技検定:K問題) を解いた
bouzuya/rust-sandbox bbn 0.37.0 をつくった。
bbn view
コマンドの引数として week date を取れるようにした。ぼくは 2023-W27-4 のような week date を使うことが多いので、その形式を取れると便利だなと思って変更した。
structopt → clap のアップデートも入れている。他にも古い点がたくさんあるのだけど今回は対応しないことにした。
- 的あて (第五回 アルゴリズム実技検定:K問題)
https://atcoder.jp/contests/past202012-open/tasks/past202012_k
- https://atcoder.jp/contests/past202012-open/submissions/43280533
- PAST 上級本 P.158
- 解説 AC
- 計算式の両辺に DP の同じ状態が出てくるもの
- うまく変形すると消せる
use proconio::{input, marker::Chars};
fn main() {
input! {
s: [Chars; 4],
}
let (h, w) = (4, 4);
let to_bit = |i: usize, j: usize| -> usize { 1 << (i * w + j) };
let grid = {
let mut grid = 0_usize;
for i in 0..h {
for j in 0..w {
if s[i][j] == '#' {
grid |= to_bit(i, j);
}
}
}
grid
};
let mut dp = vec![std::f64::MAX; 1 << (h * w)];
dp[0] = 0_f64;
for s in 0..(1 << (h * w)) {
for i in 0..h {
for j in 0..w {
let mut ps = vec![];
let dir = vec![(-1, 0), (0, -1), (0, 0), (0, 1), (1, 0)];
for (dr, dc) in dir.iter().copied() {
let (nr, nc) = (i as i64 + dr, j as i64 + dc);
if !(0..h as i64).contains(&nr) || !(0..w as i64).contains(&nc) {
continue;
}
let (nr, nc) = (nr as usize, nc as usize);
if (s & to_bit(nr, nc)) == 0 {
continue;
}
ps.push(s ^ to_bit(nr, nc));
}
if ps.is_empty() {
continue;
}
dp[s] = dp[s].min(
ps.iter().copied().map(|p| dp[p]).sum::<f64>() / ps.len() as f64
+ dir.len() as f64 / ps.len() as f64,
);
}
}
}
let ans = dp[grid];
println!("{}", ans);
}
今日のコミット。