HDU6006 Engineer Assignment 状压DP
程序员文章站
2022-05-22 09:57:44
...
简略题意:n个项目,m个工程师,每个工程师可以提供Di种技术支持,每个项目需要Ci种技术,每个工程师只能属于一个项目。问最多能完成几个项目。
因为每个工程师只能被用一次,那么根据当前还剩哪些工程师空闲,我们就可以知道当前这个项目能不能被完成。
用dp[i][j]代表当前处理到第i个项目,还剩下的工程师集合是j。
转移有两种:
1. 不做当前的项目, dp[i+1][j] = dp[i][j]。
2. 做当前的项目,那么可用的工程师集合s即可有若干种,可以预先处理出来。
那么转移有若(j&s) == s, dp[i+1][j^s] = dp[i][j] + 1。
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double eps = 1e-8;
int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;
namespace solver {
int t, n, m;
struct A {
int k;
int v[3];
void in() {
for(int i = 0; i < k; i++)
scanf("%d", &v[i]);
}
};
int dp[11][1025];
vector<int> need[11];
void umax(int &a, int b) {
a = max(a, b);
}
int f = 0;
void solve() {
scanf("%d", &t);
while(t--) {
memset(dp, 0, sizeof dp);
for(int i = 0; i < 11; i++)
need[i].clear();
scanf("%d%d", &n, &m);
vector<A> V1, V2;
for(int i = 1; i <= n; i++) {
A buf;
scanf("%d", &buf.k);
buf.in();
V1.push_back(buf);
}
for(int i = 1; i <= m; i++) {
A buf;
scanf("%d", &buf.k);
buf.in();
V2.push_back(buf);
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < (1<<m); j++) {
map<int, int> mp;
for(int k = 0; k < m; k++) {
if(j & (1 << k)) {
for(int p = 0; p < V2[k].k; p++) {
mp[V2[k].v[p]] = 1;
}
}
}
bool isok = 1;
for(int p = 0; p < V1[i].k; p++) {
if(mp[V1[i].v[p]] == 0)
isok = 0;
}
if(isok)
need[i].push_back(j);
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < (1 << m); j++) {
umax(dp[i+1][j], dp[i][j]);
for(auto s:need[i]) {
if((s & j) == s)umax(dp[i+1][j^s], dp[i][j] + 1);
}
}
}
int ans = 0;
for(int i = 0; i < (1 << m); i++)
ans = max(ans, dp[n][i]);
printf("Case #%d: %d\n", ++f, ans);
}
}
}
int main() {
#ifdef file
freopen("gangsters.in", "r", stdin);
freopen("gangsters.out", "w", stdout);
#endif // file
solver::solve();
return 0;
}