题目描述:
问题描述:给定一个有n个正整数的数组a和一个整数sum,求选择数组a中部分数字和为sum的方案数。若两种选取方案有一个数字的下标不一样,则认为是不同的方案。
输人描述:输人为两行,第1行为两个正整数n(1≤n≤1000)、sum(1≤sum≤1000),第2行为n个正整数a[i](32位整数),以空格隔开。
输出描述:输出所求的方案数。
输入样例:
5 15
5 5 10 2 3
输出样例:
4
思路:经典的背包问题求方案种数,定义f[i][j]为从前i个数中选,和为j的方案种数。则状态转移方程为
不选第i个数:f[i][j] += f[i - 1][j]
选第i个数:f[i][j] += f[i - 1][j - w[i]
这里使用滚动数组优化,具体细节见代码:
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 1010;
int n, m, w[N], f[N];
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++ ) cin >> w[i];
f[0] = 1;
for(int i = 1; i <= n; i ++ )
for(int j = m; j >= w[i]; j -- )
f[j] += f[j - w[i]];
cout << f[m] << endl;
return 0;
}