[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;
}

猜你喜欢

转载自blog.csdn.net/Estia_/article/details/83756411
今日推荐