use std::ops::{Add, Sub};
pub fn knapsack_01<W, V>(weights: &[W], values: &[V], capacity: W) -> V
where
W: Copy + PartialOrd + Sub<Output = W> + From<u8> + Into<usize>,
V: Copy + Add<Output = V> + Ord + Default,
{
let n = weights.len();
let cap = <W as Into<usize>>::into(capacity);
let mut dp = vec![vec![V::default(); cap + 1]; n + 1];
for i in 1..=n {
for w in 0..=cap {
let weight_i_1 = <W as Into<usize>>::into(weights[i - 1]);
if weight_i_1 <= w {
let include = values[i - 1] + dp[i - 1][w - weight_i_1];
let exclude = dp[i - 1][w];
dp[i][w] = if include > exclude { include } else { exclude };
} else {
dp[i][w] = dp[i - 1][w];
}
}
}
dp[n][cap]
}