結果
| 問題 |
No.2955 Pizza Delivery Plan
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-11-08 22:58:02 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 390 ms / 2,000 ms |
| コード長 | 2,454 bytes |
| コンパイル時間 | 14,122 ms |
| コンパイル使用メモリ | 378,228 KB |
| 実行使用メモリ | 66,176 KB |
| 最終ジャッジ日時 | 2024-11-08 22:58:24 |
| 合計ジャッジ時間 | 21,984 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 28 |
ソースコード
use proconio::input;
const ORIGIN: (f64, f64) = (0.0, 0.0);
fn main() {
input! {
(n, k): (usize, usize),
xy: [(f64, f64); n],
}
// dp[S][i][j]
// S: 既に完了した注文の集合
// i: 現在位置
// j: 手持ちのピザの個数
let mut dp: Vec<Vec<Vec<Option<f64>>>> = vec![vec![vec![None; k]; n + 1]; 1 << n];
for pos in 0..n {
dp[1 << pos][pos][k - 1] = Some(calc_distance(ORIGIN, xy[pos]));
}
for bits in 0_usize..1 << n {
for from in 0..n {
for num_pizzas in 0..k {
let Some(cost) = dp[bits][from][num_pizzas] else {
continue;
};
for to in 0..n {
if bits >> to & 1 == 1 {
continue;
}
if num_pizzas >= 1 {
chmin_for_option(
&mut dp[bits | 1 << to][to][num_pizzas - 1],
cost + calc_distance(xy[from], xy[to]),
);
}
chmin_for_option(
&mut dp[bits | 1 << to][to][k - 1],
cost + calc_distance_via_origin(xy[from], xy[to]),
);
}
}
}
}
let mut min_cost = None;
for pos in 0..n {
for num_pizzas in 0..k {
if let Some(cost) = dp[(1 << n) - 1][pos][num_pizzas] {
chmin_for_option(&mut min_cost, cost + calc_distance(xy[pos], ORIGIN));
}
}
}
println!("{}", min_cost.unwrap());
}
fn calc_distance(coord1: (f64, f64), coord2: (f64, f64)) -> f64 {
(coord1.0 - coord2.0).hypot(coord1.1 - coord2.1)
}
fn calc_distance_via_origin(coord1: (f64, f64), coord2: (f64, f64)) -> f64 {
calc_distance(coord1, ORIGIN) + calc_distance(ORIGIN, coord2)
}
/// If `value` is `None` or contains a value greater than `cand_value`, update it to `Some(cand_value)`.
///
/// Returns whether `value` has been updated or not as a bool value.
///
/// # Arguments
///
/// * `value` - Reference variable to be updated.
/// * `cand_value` - Candidate value for update.
pub fn chmin_for_option<T>(value: &mut Option<T>, cand_value: T) -> bool
where
T: PartialOrd,
{
if value.as_ref().is_some_and(|cost| cost <= &cand_value) {
return false;
}
*value = Some(cand_value);
true
}