题目大意:给你n个数和s,问最多将n分为多少组,使每组通过加减操作能得到s的组数最多,输出组数
接下来粘贴大神代码,以便学习
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long lint;
int n, s, T, a[20];
int sum[1 << 20], f[1 << 20], g[1 << 20];
int main() {
//freopen( "A.in", "r", stdin );
scanf( "%d", &T );
while ( T -- ) {
scanf( "%d%d", &n, &s );
for ( int i = 0; i < n; i ++ ) {
scanf( "%d", &a[i] );
}
for ( int i = 0; i < (1 << n); i ++ ) { //遍历所有子集
sum[i] = 0;
for ( int j = 0; j < n; j ++ ) if ( (i >> j) & 1 ) {
sum[i] += a[j];
}
}
for ( int i = 0; i < (1 << n); i ++ ) {<span style="white-space:pre"> </span>//查看子集的子集是否有满足条件
f[i] = ( sum[i] == s );
for ( int j = (i - 1) & i; j; j = (j - 1) & i ) {
f[i] |= ( sum[j] + s == sum[i - j] || sum[j] - s == sum[i - j] );
}
}
g[0] = 0;
int ans = 0;
for ( int mask = 0; mask < (1 << n); mask ++ ) { //维护取最大值
g[mask] = f[mask];
for ( int sub = mask & (mask - 1); sub; sub = ( sub - 1 ) & mask ) {
g[mask] = max( g[mask], g[sub] + g[mask - sub] );
}
ans = max( ans, g[mask] );
}
cout <<ans<<endl;
}
return 0;
}