标签:des style os io for ar 问题 div
4 2 3 10 10 6 6 6 2 0 1 2 1 2 0 1 0 1 0 0 0 0 0 2 3 10 10 8 10 6 1 0 1 2 0 1 0 1 0 0 0 0 0 2 3 10 10 8 10 6 1 0 1 2 0 1 0 0 0 0 0 0 0 2 3 10 10 8 10 6 1 0 1 2 0 0 0 1 0 0 0 0 0
Case #1: 2 Case #2: 4 Case #3: 4 Case #4: 6 题意:给你n个工程,m个问题,每个工程都有对应要解决的问题,每个问题还有关联问题,问你最大的收益 思路:DP的方法,首先预处理出每个工程要完成的问题,用二进制表示,然后就是dp结果,每个工程我们有做与不做的可能,记忆化搜索,当我们在面对第u个工程的时候, 如果当前的问题已经处理的状态出现过的话,我们也已经记录过了,直接返回#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <map> #include <vector> typedef __int64 ll; using namespace std; const int maxn = 100; int G[maxn][maxn], pj[maxn], pb[maxn]; vector<int> solve[maxn]; int n, m; ll sum, status, need[maxn]; map<ll, ll> mp[maxn]; void dfs(int u) { if (status & (1<<u)) return; status |= (1<<u); for (int i = 0; i < m; i++) if (G[u][i]) dfs(i); } ll dp(int u, ll st) { if (u >= n) return 0; if (mp[u].find(st) != mp[u].end()) return mp[u][st]; ll tmp = dp(u+1, st); ll sum = pj[u]; for (int i = 0; i < m; i++) if (!(st & (1<<i)) && (need[u] & (1<<i))) sum -= pb[i]; tmp = max(tmp, sum + dp(u+1, st | need[u])); return mp[u][st] = tmp; } int main() { int t, cas = 1; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &pj[i]); for (int i = 0; i < m; i++) scanf("%d", &pb[i]); int num, tmp; for (int i = 0; i < n; i++) { mp[i].clear(); solve[i].clear(); scanf("%d", &num); for (int j = 0; j < num; j++) { scanf("%d", &tmp); solve[i].push_back(tmp); } } for (int i = 0; i < m; i++) for (int j = 0; j < m; j++) scanf("%d", &G[i][j]); for (int i = 0; i < n; i++) { status = 0; int size = solve[i].size(); for (int j = 0; j < size; j++) dfs(solve[i][j]); need[i] = status; } printf("Case #%d: %I64d\n", cas++, dp(0, 0)); } return 0; }
HDU - 4971 A simple brute force problem. (DP),布布扣,bubuko.com
HDU - 4971 A simple brute force problem. (DP)
标签:des style os io for ar 问题 div
原文地址:http://blog.csdn.net/u011345136/article/details/38739509