zoukankan      html  css  js  c++  java
  • hdu6006 Engineer Assignment 状压dp

    hdu6006 

    题意:有 n 个工程, m 个人,每个工程需要 ci 个领域的知识,每个人精通 di 个领域。每个人只能去一个工程,问最多可完成多少个工程。

    tags:数据范围小,状压

    dp[i][j] 代表前 i 个工程在状态 j 的组合下,最多能完成多少个工程。

    首先预处理出每个工程可由哪些人组合完成,用 0 ~ ((1<<m)-1)记录。这里有点麻烦。。

    然后就是 dp 转移,在考虑到第 i 个工程时:

    1】如不取这个工程,则 dp[i][j] = max(dp[i][j] , dp[i-1][j] ) ;

    2】如取,则 dp[i][j] = max(dp[i][j] , dp[i-1][j^v]+1 ) ,   要求满足 j 包含 v 。

    其实类似于背包。。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 200005;
    
    int T, n, m, a[15][5], c[15], dp[15][1<<13], di, tmp;
    vector<int > ve1[15], ve2[110];
    void Init()
    {
        rep(i,0,14) ve1[i].clear();
        rep(i,0,109) ve2[i].clear();
        mes(dp, 0);
    }
    int main()
    {
        scanf("%d", &T);
        rep(cas,1,T)
        {
            scanf("%d%d", &n, &m);
            Init();
            rep(i,1,n)
            {
                scanf("%d", &c[i]);
                rep(j,1,c[i]) scanf("%d", &a[i][j]);
            }
            rep(i,0,m-1)
            {
                scanf("%d", &di);
                rep(j,1,di) scanf("%d", &tmp), ve2[tmp].PB(i);
            }
    
            rep(ci,1,n)   // Init
            {
                for(auto i : ve2[a[ci][1]])
                {
                    if(c[ci]==1) { ve1[ci].PB( (1<<i) ); continue; }
                    for(auto j : ve2[a[ci][2]])
                    {
                        if(c[ci]==2) { ve1[ci].PB( (1<<i)|(1<<j) ); continue; }
                        for(auto l : ve2[a[ci][3]])
                            ve1[ci].PB( (1<<i)|(1<<j)|(1<<l) );
                    }
                }
            }
    
            rep(i,1,n) rep(j,0,(1<<m)-1)
            {
                for(auto v : ve1[i])
                {
                    if((j|v)==j)
                        dp[i][j] = max(dp[i][j], dp[i-1][j^v]+1);
                }
                dp[i][j] = max(dp[i][j], dp[i-1][j]);
            }
    
            int ans = 0;
            rep(j,0,(1<<m)-1)  ans = max(ans, dp[n][j]);
            printf("Case #%d: %d
    ", cas, ans);
        }
    
        return 0;
    }
  • 相关阅读:
    flashdevelop生成swc库(转)
    SOG and COG spec
    [C]switch...case...一个case包含多个值的一种写法
    [C]赋值语句返回值
    Antenna知识整理
    SPI接口比IIC速度快的理解
    C语言代码的换行
    SRRC认证
    蓝牙协议分析(6)_BLE地址类型
    结构体变量和指针对成员的引用形式
  • 原文地址:https://www.cnblogs.com/sbfhy/p/7528981.html
Copyright © 2011-2022 走看看