1. 程式人生 > >[BZOJ3717] [PA2014] Pakowanie [狀態壓縮][dp]

[BZOJ3717] [PA2014] Pakowanie [狀態壓縮][dp]

[ L i n k \frak{Link} ]


卡時狀壓
2

n n \frak{2^nn} 過不了,得列舉有 1 \frak{1} 的位,把複雜度降到 2
n 1 n \frak{2^{n-1}n}
。。。

#include<cstdio>
#include<iostream>
#include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<ctime> using namespace std; #define update(dx, df, dr) if ( (df < f[dx]) || (df == f[dx] && dr > r[dx]) ) f[dx] = df, r[dx] = dr int n, m; int a[16777255]; int c[105]; int f[16777255]; int r[16777255]; inline bool cmp (const int &a, const int &b) { return a > b; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); for (int i = 1; i <= m; ++i) scanf("%d", &c[i]); for (int i = n; i >= 1; --i) a[1 << i - 1] = a[i]; sort(c + 1, c + 1 + m, cmp); int up = (1 << n); for (int lowbit, v, i = 1; i < up; ++i) { f[i] = m + 1; for (int j = i; j; j ^= lowbit) { lowbit = j & -j; v = i ^ lowbit; if (a[lowbit] <= r[v]) { update(i, f[v], r[v] - a[lowbit]); } else if (a[lowbit] <= c[f[v] + 1]) { update(i, f[v] + 1, c[f[v] + 1] - a[lowbit]); } } } if (f[up - 1] > m) printf("NIE"); else printf("%d",f[up - 1]); return 0; }