问题描述:
样例说明与规模限制:
满分代码:
#include <iostream>
#include <algorithm>
using namespace std;
int w[105];
//dp[i][j],i表示前i个砝码,就表示前i个砝码可能凑成的重量,若dp[i][j]==1则可以凑成,为0则不可以
int dp[105][100000];
long long sum = 0;
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> w[i];
sum += w[i];
}
for (int i = 1; i <= n; i++) {
//继承上一轮数据的结果,若前i-1个砝码能凑成,则前i个也必定能凑成
for (int j = 1; j <= sum; j++) {
dp[i][j] = dp[i - 1][j];
}
for (int j = 1; j <= sum; j++) {
if (dp[i][j] == 0) {
//若前i个砝码重量为j则一定能凑出重量j
if (w[i] == j) {
dp[i][j] = 1;
}
//若前i-1个砝码能凑出j+w[i]则将第i个砝码放在另一端则一定能凑出j
else if (dp[i - 1][j + w[i]] == 1) {
dp[i][j] = 1;
}
//若前i-1个砝码能凑出abs(j-w[i])则加上第i个砝码一定能凑出j
else if (dp[i - 1][abs(j - w[i])] == 1) {
dp[i][j] = 1;
}
}
}
}
int num = 0;
//判断前n个砝码是否能凑出重量j
for (int j = 0; j <= sum; j++) {
if (dp[n][j] == 1) {
num++;
}
}
printf("%d", num);
}