一眼感觉是毒瘤背包
第二眼看到数据范围???
这么讲的话,weight的限制就得直接判断;又没有办法存
也就是说得记录每一组放了哪些?
这样的话压缩状态需要1818当然不行啦。
记录之前分了几组、选掉了哪些数、当前这组要选哪些?
三进制状压?选掉的是2,现在选掉的是1,没选的是0?
318>3×108是没有前途的。
如果把2和1合并起来的话就可以变成:
枚举组数、每次更新状态之后、如果f(count,(1<<n)-1)≤w就跳。
有点像背包。
262144给开了个262000 不愧是我.jpg(
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cstring>
#include<cctype>
using namespace std;
int n, w, c[20], F[2][262222], limit;
bool t;
int main() {
scanf("%d%d", &n, &w);
for (int i = 1; i <= n; ++i) {
scanf("%d", &c[i]);
}
memset(F[0], 0x3f, sizeof(F));
F[0][0] = 0;
limit = (1<<n) - 1;
for (int i = 1; i <= n; ++i) {
t = i & 1;
memset(F[t], 0x3f, sizeof(F[t]));
for (int j = 0; j <= limit; ++j) {
if (F[!t][j] > w) continue;
F[t][j] = 0;
}
for (int v, j = 0; j < limit; ++j) {
if (F[t][j] > w) continue;
for (int k = 1; k <= n; ++k) {
if (j&1<<k-1) continue;
v = j|1<<k-1;
F[t][v] = min(F[t][v], F[t][j] + c[k]);
}
}
if(F[t][limit] <= w) {
printf("%d", i);
return 0;
}
}
return 0;
}