解释
全部放左边
第一次循环表示,前i
个物品的权值只能为0,1的集合
第二次循环,将右边等效到左边
第二次循环表示,前i
个物品的权值为0,1,-1,其他权值可以为0,1的集合
- 具体思路,和解析请看如下图片。
- 一些中间过程
// 000001 // 0
// 000010 // 1
// 000011 // 0 + 1
// 00001100 // 2
// 00001111 // 0 + 1 + 2
// 00001111000 // 3
// 000001 // 0
// 000100 // 2
// 000101 // 0 + 2
// 0001010000 // 0+4 2+4
// 0001010101 // 0 + 2 + 4 (0,2,4,6)
// 0001010101000000 // 0 + 2 + 4 (+6)
// 0001010101010101 // 0 + 2 + 4 + 6
// 0001010101010101
代码
#include<iostream>
#include<bitset>
using namespace std;
const int N = 105, M = 100005;
int g[N], n;
bitset<M> S;
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i ++ ){
scanf("%d", &g[i]);
}
S[0] = 1;
for(int i = 0; i < n; i ++ ){
S |= S << g[i];
}
for(int i = 0; i < n; i ++ ){
S |= S >> g[i];
}
cout << S.count() - 1 << endl;
return 0;
}
思路来自 传送门