『アルゴリズムとデータ構造』を Rust で実装してみるシリーズ。5章の動的計画法。
前回 → https://quantized-cube.com/rust-dp-02
今回はナップサック問題。
use proconio::input;
fn input(use_default_values: bool) -> (usize, usize, Vec<usize>, Vec<i64>) {
if use_default_values {
let n: usize = 6;
let w: usize = 7;
let weight: Vec<usize> = vec![2, 1, 3, 2, 1, 5];
let value: Vec<i64> = vec![3, 2, 6, 1, 3, 85];
return (n, w, weight, value);
} else {
println!("Input n, w, and weight_value_pair:");
input! {
n: usize,
w: usize,
weight_value_pair: [(usize, i64); n],
}
let mut weight: Vec<usize> = Vec::new();
let mut value: Vec<i64> = Vec::new();
for item in weight_value_pair.into_iter() {
weight.push(item.0);
value.push(item.1);
}
return (n, w, weight, value);
}
}
fn chmax<T: PartialOrd>(a: &mut T, b: T) {
if *a < b {
*a = b;
}
}
/// ナップサック問題に対する動的計画法
pub fn code_5_7(use_default_values: bool) -> i64 {
// 入力
let (n, w, weight, value) = input(use_default_values);
// DP テーブル定義
let mut dp = vec![vec![0; w + 1]; n + 1];
// DPループ
for i in 0..n {
for u in 0..=w {
// i 番目の品物を選ぶ場合
if u >= weight[i] {
let b = dp[i][u - weight[i]] + value[i];
chmax(&mut dp[i + 1][u], b);
}
// i 番目の品物を選ばない場合
let b = dp[i][u];
chmax(&mut dp[i + 1][u], b);
}
}
// 最適値の出力
dp[n][w]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn code_5_7_works() {
let result = code_5_7(true);
assert_eq!(result, 90);
}
}
GitHub のリポジトリはこちら https://github.com/quantized-cube/book_algorithm_solution_rust
コメント