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;
}

浙公网安备 33010602011771号