zoukankan      html  css  js  c++  java
  • 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 }
    View Code

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

  • 相关阅读:
    redis>lua脚本
    redis百万级数据存取
    spring之自定义注解
    spring>aop
    git的回退和撤销操作
    vue2.0 v-tap简洁(漏)版 (只解决300ms问题)
    JSONP原理小记
    前端模块加载规范AMD与CMD小记
    html状态码
    使用vue-cli开发时跨域问题
  • 原文地址:https://www.cnblogs.com/danceonly/p/3901627.html
Copyright © 2011-2022 走看看