这道题是经典的dp问题,和01背包有些类似,01背包让求的是能凑出的最大值,而这道题是求的是所有可能凑出来的数。
所以这道题的状态转移方程为f[i][j]=f[i-1][j]||f[i-1][j+a[i]]||f[i-1][abs(j-a[i])];
砝码称重,具体代码
#include <bits/stdc++.h>
using namespace std;
const int N = 110, M = 2e5 + 10;
int sum;
int n;
int w[N];
bool f[N][M];
int main() {
cin>>n;
for (int i = 1; i <= n; i++)
{
scanf("%d", &w[i]);
sum+=w[i];
}
f[0][0]=true;
for (int i = 1; i <= n;i++)
for (int j = 0; j <=sum;j++)
f[i][j]=f[i-1][j]||f[i-1][j+w[i]]||f[i-1][abs(j-w[i])];
int ans = 0;
for (int i = 1; i <=sum;i++)
if(f[n][i])ans++;
cout << ans;
return 0;
}