题目大意:有一个人要搬家,他要把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;
}