首页 > 代码库 > HDU 4924 Football Manager(状压DP)
HDU 4924 Football Manager(状压DP)
题目连接 : http://acm.hdu.edu.cn/showproblem.php?pid=4924
题意 : n(<=20)个人选出11个人作为首发组成a-b-c阵容,每个人都有自己擅长的位置,并且每个人和其他人会有单向的厌恶和喜欢关系,每个人对于自己擅长的位置都有两个值CA和PA,有喜欢或者厌恶关系的两个人在一起也会影响整个首发的CA总值,要求选出一套阵容使得CA最大,或者CA一样的情况下PA最大。
思路 : 状压搞,dp[s]s的二进制表示20个人中选了那几个人,然后规定选进来的顺序就是那个人所担当的位置,这样就可以避免知道状态的情况下去算最优而外加的复杂度了。
PS :不过这道题目时限似乎卡得很紧,注意用lowbit()优化+其它一些优化,另外注意一些输入信息,关系中a和b有可能重复等细节就可以AC了。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <map> 5 6 using namespace std; 7 map<int,int> mp; 8 const int INF = 0x3f3f3f3f; 9 typedef pair<int,int> PII; 10 const int MAXN = 1<<20; 11 int lowbit(int x) {return x&-x;} 12 13 int num[MAXN] = {0}; 14 int has[MAXN] = {0}; 15 int vis[MAXN] = {0}; 16 int Has[MAXN] = {0}; 17 int ans[MAXN]; 18 int abl[55][10]; 19 PII val[55][10]; 20 PII dp[MAXN]; 21 int state[22]; 22 int G[22][22]; 23 int n; 24 int tot; 25 int E; 26 void BUG(int a[], int n) { 27 for (int i = 1; i <= n; i++) { 28 printf("%d%c", a[i], " \n"[i == n]); 29 } 30 } 31 32 void init() { 33 num[0] = 0; vis[0] = 1; 34 tot = 1; E = 0; 35 for (int i = 1; i < MAXN; i++) { 36 if (!vis[i-lowbit(i)] || num[i-lowbit(i)] == 11)continue; 37 num[i] = num[i-lowbit(i)] + 1; has[i] = tot; Has[tot] = i; vis[i] = 1; 38 if (num[i] == 11) { 39 ans[++ E] = tot; 40 } 41 tot ++; 42 } 43 for (int i = 0; i < 20; i++) { 44 vis[1<<i] = i + 1; 45 } 46 //printf("tot = %d\n", tot); 47 return ; 48 } 49 50 PII update(PII a, PII b) { 51 return a < b ? b : a; 52 /* 53 if (a.first > b.first || a.first == b.first && a.second > b.second) { 54 return a; 55 }else { 56 return b; 57 } 58 */ 59 } 60 int c1, c2, c3, c4; 61 void add(int e, char s[], int C, int P) { 62 if (e > n) while (true); 63 if (s[0] == ‘G‘) { 64 val[e][1] = make_pair(C, P); 65 abl[e][1] = 1; 66 ++ c1; 67 }else if (s[0] == ‘D‘) { 68 val[e][2] = make_pair(C, P); 69 abl[e][2] = 1; 70 ++ c2; 71 }else if (s[0] == ‘M‘) { 72 val[e][3] = make_pair(C, P); 73 abl[e][3] = 1; 74 ++ c3; 75 }else { 76 val[e][4] = make_pair(C, P); 77 abl[e][4] = 1; 78 ++ c4; 79 } 80 } 81 bool used[MAXN]; 82 void solve() { 83 memset(used, false, sizeof(used)); 84 PII ret = make_pair(-INF, -INF); 85 dp[0] = make_pair(0, 0); used[0] = 1; 86 for (int ti = 1; ti < tot; ti++) { 87 int cnt = num[Has[ti]]; 88 int i = Has[ti]; 89 dp[ti] = make_pair(-INF, -INF); 90 for (int j = i; j > 0; j -= lowbit(j)) { 91 int nex = vis[lowbit(j)]; 92 int ts = has[i-lowbit(j)]; 93 if (!used[ts]) continue; 94 if (!abl[nex][state[cnt]]) continue; 95 dp[ti] = update(dp[ti], make_pair(dp[ts].first+val[nex][state[cnt]].first, dp[ts].second+val[nex][state[cnt]].second)); 96 used[ti] = 1; 97 } 98 if (cnt == 11 && used[ti]) { 99 int tmp = 0;100 for (int j = i; j > 0; j -= lowbit(j)) {101 int now = vis[lowbit(j)];102 for (int k = j; k > 0; k -= lowbit(k)) {103 int nex = vis[lowbit(k)];104 if (now != nex)tmp += G[now][nex] + G[nex][now];105 else tmp += G[now][nex];106 }107 }108 ret = update(ret, make_pair(dp[ti].first+tmp, dp[ti].second));109 }110 }111 if (ret.first == -INF) {112 printf("Poor Manager!\n");113 }else {114 printf("%d %d\n", ret.first, ret.second);115 }116 return ;117 }118 119 int main() {120 init();121 int T;122 scanf("%d", &T);123 for (int cas = 1; cas <= T; cas++) {124 scanf("%d", &n);125 memset(abl, 0, sizeof(abl));126 memset(G, 0, sizeof(G));127 c1 = 0, c2 = 0, c3 = 0, c4 = 0;128 mp.clear();129 for (int i = 1; i <= n; i++) {130 int e, m;131 scanf("%d%d", &e, &m);132 mp[e] = i;133 char ts[5];134 int tc, tp;135 for (int j = 1; j <= m; j++) {136 scanf("%s %d%d", ts, &tc, &tp);137 add(i, ts, tc, tp);138 }139 }140 int Q;141 scanf("%d", &Q);142 while (Q--) {143 int a, b, c;144 char ts[11];145 scanf("%d%d%s%d", &a, &b, ts, &c);146 a = mp[a]; b = mp[b];147 if (ts[0] == ‘L‘) {148 G[a][b] = c;149 }else {150 G[a][b] = -c;151 }152 }153 int nd, nm, ns;154 scanf("%d-%d-%d", &nd, &nm, &ns);155 if (n < 11 || c1 < 1 || c2 < nd || c3 < nm || c4 < ns) {156 printf("Poor Manager!\n"); continue;157 }158 state[1] = 1;159 for (int i = 2; i <= nd+1; i++) state[i] = 2;160 for (int i = 2+nd; i <= nd+1+nm; i++) state[i] = 3;161 for (int i = 2+nd+nm; i <= 11; i++) state[i] = 4;162 //for (int i = 1; i <= 11; i++) printf("%d%c", state[i], " \n"[i == 11]);163 //BUG(state, 11);164 solve();165 }166 return 0;167 }
//因为免费,所以在京东搭了一个网站,玩了几天,觉得还是暂时用cnblogs吧,等我icpc结束了再去搭站玩吧 *_*
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。