WOJ 1608 Calculation(状态压缩)

来源:互联网 发布:淘宝怎么显示在线人数 编辑:程序博客网 时间:2024/06/06 01:24
题意:给出n个数(n<=14),现在可以将这n个数任意分组,每组的每个数可以在前面加上一个正号或者符号,问最多有多少组的和等于s。
思路:状态压缩,每个状态表示当前的状态可以分成多少组含有s的组,然后状态转移即可。
#include<bits/stdc++.h>#define eps 1e-6#define LL long long#define pii pair<int, int>#define pb push_back#define mp make_pair//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 1<<15;//const int INF = 0x3f3f3f3f;int n, s, a[16], dp[MAXN], sumv[MAXN];int main(){    freopen("input.txt", "r", stdin);int T;scanf("%d", &T);while (T--) {scanf("%d%d", &n, &s);memset(dp, 0, sizeof(dp));memset(sumv, 0, sizeof(sumv));for (int i = 0; i < n; i++)scanf("%d", &a[i]);for (int i = 0; i < (1<<n); i++) for (int j = 0; j < n; j++) if ((1<<j)&i) sumv[i] += a[j];for (int i = 0; i < (1<<n); i++) {dp[i] = (sumv[i] == s);for (int j = i; j; j = (j-1)&i) dp[i] |= (sumv[i^j]-sumv[j] == s);}dp[0] = 0;for (int i = 0; i < (1<<n); i++) for (int j = i; j; j = (j-1)&i) dp[i] = max(dp[i], dp[j]+dp[i^j]);printf("%d\n", dp[(1<<n)-1]);}    return 0;}

1 0