haar_lib/algo/subset_sum/
limited.rs

1//! 各要素に最大使用回数が定められている部分和問題
2
3/// 各要素に最大使用回数が定められている部分和問題
4///
5/// **Time complexity** $O(nk)$
6///
7/// **Space complexity** $O(k)$
8///
9/// # Arguments
10///
11/// * `n` - 要素数 (`== a.len()`, `== m.len()`)
12/// * `k` - 判定したい値の最大値 (0以上k以下の整数について部分和が構成できるかを判定する。)
13/// * `a` - 総和をとる数列。
14/// * `m` - `m[i]`は`a[i]`を使用できる最大回数。
15pub fn subset_sum_limited(n: usize, k: usize, a: &[usize], m: &[usize]) -> Vec<bool> {
16    assert!(a.len() == n);
17    assert!(m.len() == n);
18
19    let mut dp: Vec<isize> = vec![-1; k + 1];
20
21    dp[0] = 0;
22    for i in 0..n {
23        for j in 0..=k {
24            if dp[j] >= 0 {
25                dp[j] = m[i] as isize;
26            } else if j < a[i] || dp[j - a[i]] <= 0 {
27                dp[j] = -1;
28            } else {
29                dp[j] = dp[j - a[i]] - 1;
30            }
31        }
32    }
33
34    dp.into_iter().map(|x| x >= 0).collect()
35}