题目大意:有一个人要搬家,他要把N件家具搬到新家,给出每件家具的重量
现在他有两辆货车,载重分别为c1和c2,每次都是两辆货车一起出发,问至少要多少趟才能搬完

解题思路:先预处理出每辆货车的能搬的货,用二进制表示
接着BFS,每次找出当前状态能转移的状态即可

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = (1 << 10) + 10;
const int INF = 0x3f3f3f3f;
int n, c1, c2, totFirst, totSecond;
int w[12], dp[N];
bool first[N], second[N];
void init() {
    scanf("%d%d%d", &n, &c1, &c2);
    for (int i = 0; i < n; i++)
        scanf("%d", &w[i]);

    int Sum = 0;
    for (int i = 0; i < (1 << n); i++) {
        Sum = 0;
        for (int j = 0; j < n; j++)
            if (i & (1 << j)) Sum += w[j];
        first[i] = (Sum <= c1 ? 1 : 0);
        second[i] = (Sum <= c2 ? 1 : 0);
    }
}

int cas = 1;
void solve() {
    memset(dp, 0x3f, sizeof(dp));
    queue<int> Q;
    Q.push(0);
    dp[0] = 0;

    int end = (1 << n) - 1;
    while (!Q.empty()) {
        int u = Q.front(); Q.pop();
        int v = end - u;
        for (int i = v; i; i = v & (i - 1)) {
            for (int j = i; j; j = i & (j - 1)) {
                if ( ((first[j] && second[i - j]) || (second[j] && first[i - j]) ) && dp[u + i] > dp[u] + 1) {
                    dp[u + i] = dp[u] + 1;
                    Q.push(u + i);
                }
            }
        }
    }
    printf("Scenario #%d:\n%d\n\n", cas++, dp[end]);
}

int main() {
    int test;
    scanf("%d" ,&test);
    while (test--) {
        init();
        solve();
    }
    return 0;
}