您的位置:首页 > 其它

HDU - 6006 (状压dp)

2017-08-29 20:38 405 查看
题目网址:点击打开链接





预处理很重要:

还有后来的;(j|a[i][k])==j)j这个状态一定包含a的状态,并且没有a也一样可以完成第i个机器,

神奇的位运算

#include <iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

const int maxn=(1<<10)+2;
int dp[15][maxn];
int vis[105];
vector<int> a[15];
vector<int> project[15];
vector<int> people[15];
int t,n,m;
int main()
{
// freopen("foreign.in","r",stdin);
// freopen("foreign.out","w",stdout);
cin>>t;
for(int ka=1;ka<=t;ka++)
{
memset(dp,0,sizeof(dp));
cin>>n>>m;
for(int i=0;i<=n;i++)
{
a[i].clear();
project[i].clear();
}
for(int i=0;i<m;i++)
people[i].clear();
int r,c;
for(int i=1;i<=n;i++)
{
cin>>r;
for(int j=0;j<r;j++)
{
int x;
cin>>x;
project[i].push_back(x);
}
}
for(int i=0;i<m;i++)
{
cin>>c;
for(int j=0;j<c;j++)
{
int x;
cin>>x;
people[i].push_back(x);
}
}
for(int i=0;i<(1<<m);i++)
{
memset(vis,0,sizeof(vis));
for(int j=0;j<m;j++)
{
if(i&(1<<j))
{
for(int k=0;k<people[j].size();k++)
vis[people[j][k]]=1;
}
}
for(int j=1;j<=n;j++)
{
int ff=0;
for(int k=0;k<project[j].size();k++)
{
if(!vis[project[j][k]])
ff=1;
}
if(!ff)
a[j].push_back(i);
}
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<(1<<m);j++)
{
for(int k=0;k<a[i].size();k++)
{
if((j|a[i][k])==j) //i一定可以做
{
dp[i][j]=max(dp[i-1][j-a[i][k]]+1,dp[i][j]);
}
}
dp[i][j]=max(dp[i][j],dp[i-1][j]);//如果不带i
}
}
printf("Case #%d: %d\n",ka,dp
[(1<<m)-1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: