萌新刚学OI, 35分求助
查看原帖
萌新刚学OI, 35分求助
394339
Ambel楼主2022/10/10 16:30

思路与题解思路一致,后13个点WA

#include<bits/stdc++.h>
#define lowbit(x) (x & -x)
#define ll long long

using namespace std;

const int N = 15, M = 1e5 + 5;

int n, m, a[N][M], l2g[1 << N];
vector<int> b[N]; bool p[M], s[1 << N];
ll f[N][1 << N], cnt[N][1 << N];
//l2g[i]表示log2(i)
//s[i]表示在同一层以i的方式修地铁是否可行
//cnt[i][j]表示在第i层以j的方式修地铁的花费

inline int read() {
	int x = 0, f = 1; char c = getchar();
	for (; !isdigit(c); c = getchar())
		if (c == '-') f = -1;
	for (; isdigit(c); c = getchar())
		x = x * 10 + c - '0';
	return x * f;
}

bool judge(int x) {
	fill(p, p + 1 + n, 0);
	for (int i = x; i; i -= lowbit(i)) {
		int r = l2g[lowbit(i)] + 1;
		for (int j = 0; j < b[r].size(); j++) {
			if (p[b[r][j]]) return false;
			p[b[r][j]] = true;
		}
	}
	return true;
}

ll calc(int dep, int x) {
	ll ans = 0;
	for (int i = x; i; i -= lowbit(i)) {
		int r = l2g[lowbit(i)] + 1;
		for (int j = 0; j < b[r].size(); j++)
			ans += a[dep][b[r][j]];
	}
	return ans;
}

int main() {
	n = read(); m = read();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			a[i][j] = read();
	for (int i = 1; i <= n; i++) {
		int c = read();
		for (int j = 1; j <= c; j++)
			b[i].push_back(read());
	}
	for (int i = 0, k = 1; i <= n; i++, k *= 2) l2g[k] = i;
	for (int i = 0; i < 1 << n; i++) {
		s[i] = judge(i);
		if (s[i]) for (int j = 1; j <= n; j++)
			cnt[j][i] = calc(j, i);
	}//预处理
	memset(f, 0x3f, sizeof(f)); f[0][0] = 0;
	for (int i = 1; i <= n; i++)
		for (int j = 0; j < 1 << n; j++) {
			f[i][j] = f[i - 1][j];
			for (int k = j; k; k = k - 1 & j)
				if (s[k]) f[i][j] = min(f[i][j], f[i - 1][j ^ k] + cnt[i][k]);
		}
	printf("%lld", f[n][(1 << n) - 1]);
	return 0;
}
2022/10/10 16:30
加载中...