8 ACwing 278 数字组合 题解

数字组合

题面

给定 \(N\) 个正整数 \(a_1,a_2...a_N\) ,从中选出若干个数,使它们和是 \(M\) ,求有多少种选择方案。

\(1 \le N \le 100,\ 1 \le M \le 10000, \ 1 \le a_i \le 1000\)

题解

01背包板子题,设 \(f[i][j]\) 表示考虑前 \(i\) 个数,从中选择若干个,和为 \(j\) 的方案数

转移:\(f(i,j) += f(i - 1, j - a_i)\) 时间复杂度为 \(O(NM)\) ,可以省略掉第一维,但要注意内层循环枚举顺序

code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

const int N = 110, M = 10010;

int n, m;
int a[N];
int f[M];

int main () {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    /*
    未优化第一维的版本
    f[0][0] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= m; j++) f[i][j] = f[i - 1][j];
        for (int j = a[i]; j <= m; j++) {
            f[i][j] += f[i - 1][j - a[i]];
        }
    }
    */
    f[0] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = m; j >= a[i]; j--) {
            f[j] += f[j - a[i]];
        }
    }

    cout << f[m] << endl;

    return 0;
}
posted @ 2025-10-05 17:59  michaele  阅读(24)  评论(0)    收藏  举报