考试的时候,脑子抽了。0分
(01背包) $O(n \times m)$
n是数组长度, m是砝码总和
每个砝码有三种状态:
1,不选
2,选 加
3,选 减
假设前i-1个砝码处理完毕,且能够凑出来的数存在集合S里面,对于第i个砝码
1, 不选: 对于这个题, 这个状态可以不去处理
2, 加: 把前面所有能够凑出来的数加上当前这个数, 并加到集合S里面
3, 减: 把前面所有能够凑出来的数减上当前这个数, 并加到集合S里面
上面的描述只是为了方便理解,在写代码的时候可以直接用背包来做即可
C++ 代码
#include <cstring>
#include <iostream>
using namespace std;
const int N = 110, M = 100010;
int n, m = 100000;
bool f[M], g[M];
int main()
{
cin >> n;
int w;
while(n --)
{
cin >> w;
memset(g, 0, sizeof g);
for(int i = 1;i <= m;i ++)
if(f[i])
{
g[min(m, i + w)] = true;
g[abs(i - w)] = true;
}
f[w] = true;
for(int i = 1;i <= m;i ++)
if(g[i]) f[i] = true;
}
int res = 0;
for(int i = 1;i <= m;i ++)
res += f[i];
cout << res << endl;
return 0;
}
一等奖大佬%%%