码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4924 Football Manager(状压DP)

时间:2014-08-09 22:55:29      阅读:415      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

题目连接 : 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了。

bubuko.com,布布扣
  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 }
View Code

 

//因为免费,所以在京东搭了一个网站,玩了几天,觉得还是暂时用cnblogs吧,等我icpc结束了再去搭站玩吧 *_*

HDU 4924 Football Manager(状压DP),布布扣,bubuko.com

HDU 4924 Football Manager(状压DP)

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/danceonly/p/3901627.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!