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; }