https://www.acwing.com/problem/content/167/
18只猫,每只猫有重量,车有载重上限,求最小的数量的车把猫装完,保证有解。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
//dp[i][j]表示用了i只猫,j辆缆车,最后一辆缆车的最大空间
int dp[1 << 18][19];
int a[18];
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
int n, w;
scanf("%d%d", &n, &w);
for(int i = 0; i < n; ++i)
scanf("%d", &a[i]);
memset(dp, -INF, sizeof(dp));
for(int k = 1; k <= n; ++k) {
dp[0][k] = w;
}
for(int i = 0; i < (1 << n); ++i) {
for(int j = 0; j < n; ++j) {
if((i & (1 << j)) == 0) {
for(int k = 0; k <= n; ++k) {
if(dp[i][k] >= a[j]) {
dp[i | (1 << j)][k] = max(dp[i | (1 << j)][k], dp[i][k] - a[j]);
}
if(dp[i][k] >= 0 && k + 1 <= n)
dp[i | (1 << j)][k + 1] = max(dp[i | (1 << j)][k + 1], w - a[j]);
}
}
}
/*for(int k = 0; k <= n; ++k) {
printf("dp[");
cout << bitset<5>(i);
printf("][%d]=%d\n", k, dp[i][k]);
}
puts("");*/
}
for(int k = 0; k <= n; ++k) {
if(dp[(1 << n) - 1][k] >= 0) {
printf("%d\n", k);
return 0;
}
}
}