有人说f[i|(1<<j)]>f[i]时,g[i|(1<<j)]必须更新为g[i]-w[j+1],仔细想想,这种情况下只有在f[i|(1<<j)]为无穷大的时候才会。 假如在某种情况下,f[i|(1<<j)]不为正无穷,且大于f[i],那么g[i|(1<<j)]一定大于等于g[i]-w[j+1],手动模拟一下,假如四个物品能装在三个盒子中,当然这四个物品也能装在四个盒子中,相当于把其中某些物品移到了第四个盒子中,那么装在四个盒子中的最大剩余情况一定大于等于装在三个盒子中的最大剩余情况。所以题解一作者写的没有问题,至于证明,代码加了一行判断如下:```
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<math.h>
#include<map>
#include<string.h>
#include<string>
#include<set>
using namespace std;
#define ll long long
int n, f[1 << 19] = { 0 }, h[1 << 19] = { 0 }, w[20] = { 0 }, m;
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> w[i];
}
memset(f, 63, sizeof f);
f[0] = 1;
h[0] = m;
for (int i = 0; i < (1 << n); i++)
{
for (int j = 0; j < n; j++)
{
if ((i >> j) & 1)continue;
if (h[i] >= w[j + 1] && f[i | (1 << j)] >= f[i])
{
if (f[i | (1 << j)] > f[i] && h[i | (1 << j)] > h[i] - w[j + 1])return 0;//判断
f[i | (1 << j)] = f[i];
h[i | (1 << j)] = max(h[i | (1 << j)], h[i] - w[j + 1]);
}
else if(h[i]<w[j + 1] && f[i | (1 << j)]>=f[i] + 1)
{
f[i | (1 << j)] = f[i] + 1;
h[i | (1 << j)] = max(h[i|(1<<j)], m - w[j + 1]);
}
}
}
cout << f[(1 << n) - 1];
}