zoukankan      html  css  js  c++  java
  • HDU6006:Engineer Assignment(状压DP)

    传送门

    题意

    给出n个工程,m个工程师,每个工程和工程师需要/拥有若干个技能,询问能够完成的最大工程个数,每个工程师用一次

    分析

    dp[i][j]表示前i个工程用的工程师集合为j的最大工程个数,那么有dp[i][j]=max(dp[i-1][j],dp[i-1][j^x]+1),用way[i]记录第i个工程可行的方案,然后转移就行了

    trick

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define F(i,a,b) for(int i=a;i<=b;++i)
    #define R(i,a,b) for(int i=a;i<b;++i)
    #define mem(a,b) memset(a,b,sizeof(a))
    
    int dp[11][1111];
    vector<int>a[11];
    int numa[11];
    int numb[11];
    vector<int>b[11];
    vector<int>way[11];
    int t;
    int n,m;
    int vis[101];
    
    int main()
    {
        scanf("%d",&t);
        F(qq,1,t)
        {
            scanf("%d %d",&n,&m);
            int x;
            F(i,1,n)
            {
                a[i].clear();
                way[i].clear();
                scanf("%d",numa+i);
                F(j,1,numa[i]) {scanf("%d",&x);a[i].push_back(x);} 
            }
            F(i,1,m)
            {
                b[i].clear();
                scanf("%d",numb+i);
                F(j,1,numb[i]) { scanf("%d",&x);b[i].push_back(x); }
            }
            int flag;
            mem(dp,0);
            R(i,1,(1<<m))
            {
                mem(vis,0);
                flag=1;
                for(int j=1;j<=m;++j) if(i&(1<<(j-1)))
                {
                    for(int k=0;k<numb[j];++k) vis[b[j][k]]=1;
                }
                for(int j=1;j<=n;++j)
                {
                    flag=1;
                    for(int k=0;k<numa[j];++k) if(vis[a[j][k]]==0){ flag=0;break; }
                    if(flag) {way[j].push_back(i);dp[j][i]=1;}
                }  
            }
            F(i,1,n)R(j,1,(1<<m))
            {
                dp[i][j]=max(dp[i][j],dp[i-1][j]);
                int sz=way[i].size();
                R(k,0,sz)
                {
                    x=way[i][k];
                    if((x&j)==x) dp[i][j]=max(dp[i][j],dp[i-1][j^x]+1);
                }
            }
            int ans=0;
            R(i,0,(1<<m)) ans=max(ans,dp[n][i]);
            printf("Case #%d: %d
    ",qq,ans);
        }
        return 0;
    }
    
  • 相关阅读:
    在JS和.NET中使用JSON (以及使用Linq to JSON定制JSON数据)
    转载JSON格式化工具
    bzoj3771 Triple
    hdu 2082 找单词
    bzoj 3143: [Hnoi2013]游走
    Wannafly挑战赛17 B
    基尔霍夫矩阵
    矩阵&行列式
    luogu P2421 [NOI2002]荒岛野人
    bzoj 2818: Gcd
  • 原文地址:https://www.cnblogs.com/chendl111/p/7670723.html
Copyright © 2011-2022 走看看