hdu 4971

记忆花搜索   dp

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <stack>
#include <vector>
#include <sstream>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#define FFI freopen("in.txt", "r", stdin)
#define maxn 1010
#define INF 0x3f3f3f3f
#define inf 1000000000
#define mod 1000000007
#define ULL unsigned long long
#define LL long long
#define _setm(houge) memset(houge, INF, sizeof(houge))
#define _setf(houge) memset(houge, -1, sizeof(houge))
#define _clear(houge) memset(houge, 0, sizeof(houge))
using namespace std;
 
int t, n, m, ca;
int pro[25], _cost[55], g[55][55];
LL nee[25], pre[55];
bool vis[55];
int k[25], q[25][55];
map <LL, int> pp;

LL dfs(int u) {
    if(vis[u]) return pre[u];
    vis[u] = 1;
    pre[u] |= 1LL << u; 
    for(int i = 0; i < m; ++ i) {
        if(g[u][i]) {
            pre[u] |= dfs(i);
        }
    }
    return pre[u];
}

int DP(LL cur) {
    if(pp.count(cur)) return pp[cur];
    int dd = 0, cc = 0;
    for(int i = 0; i < n; ++ i) {
        if((nee[i] & cur) == nee[i]) {
            dd += pro[i];
        }
    }
    for(int i = 0; i < m; ++ i) {
        if((cur & (1LL << i))) {
            cc += _cost[i];
        }
    }
    pp[cur] = dd-cc;
    for(int i = 0; i < n; ++ i) {
        if((nee[i] & cur) != nee[i]) {
            pp[cur] = max(pp[cur], DP(cur|nee[i]));
        }
    }
    return pp[cur];
}

int main () {
    // FFI;
    scanf("%d", &t);
    ca = 0;
    while(t --) {
        scanf("%d%d", &n, &m);
        _clear(nee);
        pp.clear();
        for(int i = 0; i < n; ++ i) {
            scanf("%d", &pro[i]);
        }
        for(int i = 0; i < m; ++ i) {
            scanf("%d", &_cost[i]);
        }
        for(int i = 0; i < n; ++ i) {
            scanf("%d", &k[i]);
            for(int j = 0; j < k[i]; ++ j) {
                scanf("%d", &q[i][j]);
            }
        }
        for(int i = 0; i < m; ++ i) {
            for(int j = 0; j < m; ++ j) {
                scanf("%d", &g[i][j]);
            }
        }
        _clear(pre);
        _clear(vis);
        for(int i = 0; i < m; ++ i) {
            if(!vis[i]) {
                dfs(i);
            }
        }
        for(int i = 0; i < n; ++ i) {
            for(int j = 0; j < k[i]; ++ j) {
                nee[i] |= pre[q[i][j]];
            }
        }
        printf("Case #%d: %d\n", ++ ca, DP(0));
    }
    return 0;
}

  

posted @ 2014-08-23 22:13  xlc2845  阅读(251)  评论(0编辑  收藏  举报