HDU 6006 Engineer Assignment:状压dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6006
题意:
在Google中,有个n项目,m个专家。第i个项目涉及c[i]个领域,分别为a[i][0]...a[i][c[i]-1]。第i个专家精通d[i]个领域,分别为b[i][0]...b[i][d[i]-1]。
如果要完成一个项目,则这个项目所涉及到的每一个领域都必须至少有一个精通该领域的专家。你作为director,可以任意分配专家,但一个专家只能去做一个项目。问你最多能够完成多少个项目。
题解:
首先表示状态:
当前考虑到第i个项目,专家的状态为state(每一位上0表示还没选,1表示已经选过了),在这之前最多能完成dp个项目。
即:dp[i][state] = max num of finished pros
如何转移:
对于第i个项目,可以做或不做。
(1)如果不做,则专家的状态state没有变化。
dp[i+1][state] = max(dp[i+1][state], dp[i][state])
(2)如果做,则首先要满足在剩下的专家中,有一些人能够完全覆盖到这个项目所涉及的领域。设这个项目可以选择的专家的方案为nex(每一位0代表不选,1代表选)。那么转移为:
if(!(state&nex)) dp[i+1][state|nex] = max(dp[i+1][state|nex], dp[i][state] + 1)
Tips:先预处理出每个项目合法的选专家的方案,存到vector中。
求dp:先枚举第i个项目,再枚举此时的状态,做或不做两种情况分别处理。
AC Code:
// dp[i][state] = max num of finished pros
// dp[i+1][state|nex] = max self and dp[i][state] + 1
// preprocess: the sequence of selected experts for each pros
// a state on exps is legal only if state_exp & state_now == 0 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#define MAX_N 15
#define MAX_C 5
#define MAX_A 105
#define MAX_S (1<<12) using namespace std; int n,m,t;
int cas=;
int ans;
int a[MAX_N][MAX_C];
int b[MAX_N][MAX_C];
int c[MAX_N];
int d[MAX_N];
bool pro[MAX_N][MAX_A];
bool exp[MAX_N][MAX_A];
int dp[MAX_N][MAX_S];
vector<int> transfer[MAX_N]; void read()
{
memset(pro,false,sizeof(pro));
memset(exp,false,sizeof(exp));
cin>>n>>m;
for(int i=;i<n;i++)
{
cin>>c[i];
for(int j=;j<c[i];j++)
{
cin>>a[i][j];
pro[i][a[i][j]]=true;
}
}
for(int i=;i<m;i++)
{
cin>>d[i];
for(int j=;j<d[i];j++)
{
cin>>b[i][j];
exp[i][b[i][j]]=true;
}
}
} bool check(int k,int state)
{
for(int i=;i<c[k];i++)
{
int ned=a[k][i];
bool flag=false;
for(int j=;j<m;j++)
{
if(((state>>j)&) && exp[j][ned])
{
flag=true;
break;
}
}
if(!flag) return false;
}
return true;
} void cal_exp()
{
for(int i=;i<n;i++)
{
transfer[i].clear();
for(int state=;state<(<<m);state++)
{
if(check(i,state)) transfer[i].push_back(state);
}
}
} void cal_dp()
{
memset(dp,,sizeof(dp));
ans=;
for(int i=;i<n;i++)
{
for(int state=;state<(<<m);state++)
{
dp[i+][state]=max(dp[i+][state],dp[i][state]);
for(int j=;j<transfer[i].size();j++)
{
int nex=transfer[i][j];
if(!(state&nex))
{
dp[i+][state|nex]=max(dp[i+][state|nex],dp[i][state]+);
}
}
}
}
} void solve()
{
cal_exp();
cal_dp();
for(int state=;state<(<<m);state++)
{
ans=max(ans,dp[n][state]);
}
} void print()
{
cout<<"Case #"<<(++cas)<<": "<<ans<<endl;
} int main()
{
cin>>t;
while(t--)
{
read();
solve();
print();
}
}
HDU 6006 Engineer Assignment:状压dp的更多相关文章
- hdu 6006 Engineer Assignment 状压dp
Engineer Assignment Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- HDU - 6006 Engineer Assignment (状压dfs)
题意:n个工作,m个人完成,每个工作有ci个阶段,一个人只能选择一种工作完成,可以不选,且只能完成该工作中与自身标号相同的工作阶段,问最多能完成几种工作. 分析: 1.如果一个工作中的某个工作阶段没有 ...
- HDU6006:Engineer Assignment(状压DP)
传送门 题意 给出n个工程,m个工程师,每个工程和工程师需要/拥有若干个技能,询问能够完成的最大工程个数,每个工程师用一次 分析 dp[i][j]表示前i个工程用的工程师集合为j的最大工程个数,那么有 ...
- hdu 3247 AC自动+状压dp+bfs处理
Resource Archiver Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Ot ...
- hdu 2825 aC自动机+状压dp
Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 5765 Bonds(状压DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5765 [题目大意] 给出一张图,求每条边在所有边割集中出现的次数. [题解] 利用状压DP,计算不 ...
- hdu 3681(bfs+二分+状压dp判断)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题.首先bfs预 ...
- hdu 4778 Gems Fight! 状压dp
转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...
- hdu 4856 Tunnels (bfs + 状压dp)
题目链接 The input contains mutiple testcases. Please process till EOF.For each testcase, the first line ...
- HDU 4272 LianLianKan (状压DP+DFS)题解
思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去 ...
随机推荐
- accp8.0转换教材第5章事务、视图、索引、备份和恢复理解与练习
知识点:事务.视图.索引.数据库的备份和恢复 一.单词部分 ①transation事务②atomicity原子性③consistency一致性④isolation隔离性 ⑤durability持久性⑥ ...
- HTTP通过请求和响应的交换达成通信
1. 通过请求和响应的交换达成通信 首先我们来看一个HTTP请求报文: GET/index.htm HTTP/1.1 HOST : hacker.jp HTTP协议起始行开头的GET表示请求访问服务器 ...
- .NetCore~Json代替了Xml
回到目录 在进行.netCore时代后,最大的变化就是对Json的使用更加主动,基本代替了之前的XML,像一些用户配置,系统配置,包包配置等都是基于json的,而web.config这个文件基本变成一 ...
- Visual Studio自动添加头部注释 -C#开发2010-2013验证
在团队开发中,头部注释是必不可少的.但在开发每次新建一个类都要复制一个注释模块也很不爽,所以得想个办法让开发工具自动生成我们所需要的模板.....操作方法如下: 找你的vs安装目录, 比如我的是在D盘 ...
- 一颗简单的JDBC栗子
前言:安装好数据库之后,我们编写的java程序是不能直接使用数据库的,而JDBC(Java Database Connectivity,即java数据库连接)是java语言里用来规范客户端程序访问数据 ...
- Linux服务器下对Oracle作Rman备份
由于工作需要,最近要对几台Linux系统下的Oracle数据库进行Rman备份,就在操作的同时,整理了一下,方便今后作为资料进行查阅. ------------------------Linux服务器 ...
- vue数据绑定原理
一.定义 vue的数据双向绑定是基于Object.defineProperty方法,通过定义data属性的get和set函数来监听数据对象的变化,一旦变化,vue利用发布订阅模式,通知订阅者执行回调函 ...
- Ubuntu-修改图片分辨率
ubuntu14.04 压缩图片default_wallpaper.jpg(2048x1536):压缩后ooo.jpg(1920x1280) if( 宽 > 高 ){ convert defau ...
- node 控制 树莓派做的天气闹钟
node 控制 树莓派做的天气闹钟 在成都上班,下雨天堵车,迟到的概率会很大. 正好手上有一块树莓派 ,做了一个晴雨闹钟. 下雨天 早上 7:00叫我起床 晴天 早上 7:30叫我起床 将自己喜欢的歌 ...
- mongodb中limit与skip方法
Mongodb Limit()方法 如果需要在mongodb中获取指定数量的数据记录,这时候就要用到limit()方法,该方法需要接收一个数字参数 基本语法: DB.COLLECTION_NAME. ...