HDU-4924-Football Manager(DFS+DP)

Problem Description

Football Manager is a series of football management simulation games developed by Sports Interactive and published by Sega. In this game, you will play a role of a football club manager and conduct your team to chase championship
titles. As a football team manager, you need to take responsibilities for tactics developing, training arrangements, on-pitch commanding, player trading, etc. One of the most important things is to select your starting line-up.

According to the rules of football matches, there should be 11 players in your starting line-up, where one of them must be a goalkeeper. Besides the goalkeeper (GK), there’re three classes of positions: defender (DF), midfielder (MF), and striker (ST).

When a manager is selecting his starting line-up, he usually determines the formation first. The football formation is usually noted like “4-4-2”“4-5-1”“4-3- 3”, etc. For example, the “4-5-1” formation denotes that there are 4 defenders, 5 midfielders and 1
striker. Note that every player has his preferred positions, and they will always refuse to appear at positions he does not prefer, while some excellent players may be qualified for several positions. For example, C. Ronaldo can play as both a striker and
a midfielder.

In the game, players have two important attributes for each of his preferred positions: CA (current ability) and PA (potential ability). The CA of the line-up is defined as the sum of the 11 players’ CA in the formation. Similar to CA, the
PA of the line-up equals to the sum of 11 players’ PA. Then your task is to select the proper players to reach maximum CA of your line-up. When a tie occurs, the one of maximum PA is required.

Beyond these requirements and limits, the relationships between players also make sense to the CA of your line-up. Every player may like or dislike some of his teammates. When he and the one he likes are both on the pitch, the CA of the line-up will be increased
by a specific value. On the contrary, when someone and his disliked player occurs on the pitch concurrently, the line-up’s CA will be decreased. Be careful that the like and dislike relationships between players are unidirectional. Not surprisingly, Plane.Gao
likes Messi very much while Messi may not know Plane.Gao at all.

Input

The input contains multiple test cases. The first line of input gives the number of test cases T (1<=T<=20).

For each test case, the first line contains an integer N (1<=N<=20), the total number of players in your team.

Each of the following N lines describe a player in the following format:

<SquadNum> <PositionNum> <pos1> <CA1> <PA1> <pos2> <CA2> <PA2> . . . <posnum><CAnum><PAnum>

Here:

<SquadNum> denotes the player’s unique squad number (between 1 and 99, inclusive).

<PositionNum> denotes the number of positions he preferred.

<pos1> <pos2> . . . <posnum> are strings chosen in {GK, DF, MF, ST},denoting all his preferred positions.

<CAi> denotes his CA at <posi>.

<PAi> denotes his PA at <posi>.

(0<=|P Ai|,|C Ai|<=1000,note P A and CA can be negative here.)

After the description of the player list, the following line will give an integer M (0<=M<=N (N - 1)), which indicates the number of relationships between the teammates. Then each of the following M lines is shown in the following format:

<SquadNumA> <SquadNumB > Like/Dislike <value>

Here:

<SquadNumA> denotes Player A’s Squad Number.

<SquadNumB> denotes Player B’s Squad Number.

Like/Dislike denotes the property of the relationship.

<value> denotes that when both of them appear in your starting line-up, the CA of line-up will be increased/decreased by value(0<=value<=100).

No two relationships of the same pair of teammates will occur.

The last line of each test case shows the formation that you have determined. We guarantee that the formation is legal.

You may take the sample for more details.

Output

For each test case, you should output two integers in a line, the best CA and PA of your line-up. If you can even not round up your line-up, please output “Poor Manager!” (without quotes)

Sample Input

2
15
1 1 GK 150 160
2 1 DF 150 160
3 1 DF 150 160
4 1 DF 150 160
5 1 DF 150 160
6 1 MF 150 160
7 1 MF 150 160
8 1 MF 150 160
9 1 ST 150 160
10 1 MF 150 160
11 1 ST 150 160
12 1 GK 130 150
13 1 DF 130 150
14 1 MF 130 150
15 1 ST 130 150
2
15 9 Like 10
2 13 Dislike 20
4-4-2

11
1 1 GK 150 160
2 1 DF 150 160
3 1 DF 150 160
4 1 DF 150 160
5 1 DF 150 160
6 1 MF 150 160
7 1 MF 150 160
8 1 MF 150 160
9 1 ST 150 160
10 1 MF 150 160
11 1 ST 150 160
0
4-3-3

Sample Output

1650 1760
Poor Manager!

Author

BUPT

Source

2014 Multi-University Training Contest 6

思路:先dfs枚举出所有选11个人作为队员的情况,枚举出来之后如果最大的可能都不够ansc大或者不能构成足球队的话就直接返回,之后再用DP求出最大值。

#include <stdio.h>
#define INF 99999999
#define max(A,B)(A>B?A:B)

struct S{
int c[4],p[4],mx;
bool flag[4];
}node[20];

int n,hash[100],add[20][20],a,b,c,ansc,ansp,df,mf,st,gk,attach,dpc[13][3][13][13],dpp[13][3][13][13],sel[13];

void dfs(int now,int cnt)
{
    if(cnt==11)
    {
        int i,j,k,l,mx;

        attach=0;

        for(i=0;i<11;i++) for(j=0;j<11;j++) attach+=add[sel[i]][sel[j]];

        mx=0;

        for(i=0;i<11;i++) mx+=node[sel[i]].mx;

        if(mx+attach<ansc) return;//最优化剪枝

        gk=df=mf=st=0;

        for(i=0;i<11;i++)
        {
            if(node[sel[i]].flag[0]) gk++;
            if(node[sel[i]].flag[1]) df++;
            if(node[sel[i]].flag[2]) mf++;
            if(node[sel[i]].flag[3]) st++;
        }

        if(gk<1 || df<a || mf<b || st<c) return;//不能构成足球队

        for(i=0;i<=11;i++) for(j=0;j<=1;j++) for(k=0;k<=a;k++) for(l=0;l<=b;l++) dpc[i][j][k][l]=-INF;

        dpc[0][0][0][0]=dpp[0][0][0][0]=0;

        for(i=0;i<11;i++)
        {
            for(j=0;j<=1;j++)
            {
                for(k=0;k<=a;k++)
                {
                    for(l=0;l<=b;l++)
                    {
                        if(dpc[i][j][k][l]!=-INF)
                        {
                            if(node[sel[i]].flag[0])
                            {
                                if(dpc[i+1][j+1][k][l]<dpc[i][j][k][l]+node[sel[i]].c[0])
                                {
                                    dpc[i+1][j+1][k][l]=dpc[i][j][k][l]+node[sel[i]].c[0];
                                    dpp[i+1][j+1][k][l]=dpp[i][j][k][l]+node[sel[i]].p[0];
                                }
                                else if(dpc[i+1][j+1][k][l]==dpc[i][j][k][l]+node[sel[i]].c[0])
                                {
                                    dpp[i+1][j+1][k][l]=max(dpp[i][j][k][l]+node[sel[i]].p[0],dpp[i+1][j+1][k][l]);
                                }
                            }

                            if(node[sel[i]].flag[1])
                            {
                                if(dpc[i+1][j][k+1][l]<dpc[i][j][k][l]+node[sel[i]].c[1])
                                {
                                    dpc[i+1][j][k+1][l]=dpc[i][j][k][l]+node[sel[i]].c[1];
                                    dpp[i+1][j][k+1][l]=dpp[i][j][k][l]+node[sel[i]].p[1];
                                }
                                else if(dpc[i+1][j][k+1][l]==dpc[i][j][k][l]+node[sel[i]].c[1])
                                {
                                    dpp[i+1][j][k+1][l]=max(dpp[i][j][k][l]+node[sel[i]].p[1],dpp[i+1][j][k+1][l]);
                                }
                            }

                            if(node[sel[i]].flag[2])
                            {
                                if(dpc[i+1][j][k][l+1]<dpc[i][j][k][l]+node[sel[i]].c[2])
                                {
                                    dpc[i+1][j][k][l+1]=dpc[i][j][k][l]+node[sel[i]].c[2];
                                    dpp[i+1][j][k][l+1]=dpp[i][j][k][l]+node[sel[i]].p[2];
                                }
                                else if(dpc[i+1][j][k][l+1]==dpc[i][j][k][l]+node[sel[i]].c[2])
                                {
                                    dpp[i+1][j][k][l+1]=max(dpp[i][j][k][l]+node[sel[i]].p[2],dpp[i+1][j][k][l+1]);
                                }
                            }

                            if(node[sel[i]].flag[3])
                            {
                                if(dpc[i+1][j][k][l]<dpc[i][j][k][l]+node[sel[i]].c[3])
                                {
                                    dpc[i+1][j][k][l]=dpc[i][j][k][l]+node[sel[i]].c[3];
                                    dpp[i+1][j][k][l]=dpp[i][j][k][l]+node[sel[i]].p[3];
                                }
                                else if(dpc[i+1][j][k][l]==dpc[i][j][k][l]+node[sel[i]].c[3])
                                {
                                    dpp[i+1][j][k][l]=max(dpp[i][j][k][l]+node[sel[i]].p[3],dpp[i+1][j][k][l]);
                                }
                            }
                        }
                    }
                }
            }
        }

        dpc[11][1][a][b]+=attach;

        if(ansc<dpc[11][1][a][b]) ansc=dpc[11][1][a][b],ansp=dpp[11][1][a][b];
        else if(ansc==dpc[11][1][a][b]) ansp=max(dpp[11][1][a][b],ansp);

        return;
    }

    if(now>=n || cnt+n-now<11) return;

    sel[cnt]=now;
    dfs(now+1,cnt+1);//选

    dfs(now+1,cnt);//不选
}

int main()
{
    int T,i,j,t,id,val;
    char s[5];

    scanf("%d",&T);

    while(T--)
    {
        scanf("%d",&n);

        for(i=0;i<n;i++)
        {
            scanf("%d",&t);

            hash[t]=i;

            for(j=0;j<4;j++) node[i].flag[j]=0;

            node[i].mx=-INF;

            scanf("%d",&t);

            while(t--)
            {
                scanf("%s",s);

                if(s[0]=='G') id=0;
                else if(s[0]=='D') id=1;
                else if(s[0]=='M') id=2;
                else id=3;

                scanf("%d%d",&node[i].c[id],&node[i].p[id]);

                node[i].mx=max(node[i].mx,node[i].c[id]);
                node[i].flag[id]=1;
            }
        }

        scanf("%d",&t);

        for(i=0;i<n;i++) for(j=0;j<n;j++) add[i][j]=0;

        while(t--)
        {
            scanf("%d%d%s%d",&a,&b,s,&val);

            if(s[0]=='D') add[hash[a]][hash[b]]=-val;
            else add[hash[a]][hash[b]]=val;
        }

        scanf("%d-%d-%d",&a,&b,&c);

        ansc=ansp=-INF;

        dfs(0,0);

        if(ansc>-INF) printf("%d %d\n",ansc,ansp);
        else printf("Poor Manager!\n");
    }
}

HDU-4924-Football Manager(DFS+DP),布布扣,bubuko.com

时间: 2024-08-08 05:20:00

HDU-4924-Football Manager(DFS+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个人中选了那几个人,然后规定选进来的顺序

HDU 1078 FatMouse and Cheese ( DP, DFS)

HDU 1078 FatMouse and Cheese ( DP, DFS) 题目大意 给定一个 n * n 的矩阵, 矩阵的每个格子里都有一个值. 每次水平或垂直可以走 [1, k] 步, 从 (0, 0) 点开始, 下一步的值必须比现在的值大. 问所能得到的最大值. 解题思路 一般的题目只允许 向下 或者 向右 走, 而这个题允许走四个方向, 所以状态转移方程为 dp(x, y) = dp(nextX, nextY) + arr(x, y); dp 代表在 x, y 的最大值. 由于 下一

HDU 2089 不要62(数位DP,三种姿势)

HDU 2089 不要62(数位DP,三种姿势) ACM 题目地址:HDU 2089 题意: 中文题意,不解释. 分析: 100w的数据,暴力打表能过 先初始化dp数组,表示前i位的三种情况,再进行推算 直接dfs,一遍搜一变记录,可能有不饥渴的全部算和饥渴的部分算情况,记录只能记录全部算(推荐看∑大的详细题解Orz) 代码: 1. 暴力 (以前写的) /* * Author: illuz <iilluzen[at]gmail.com> * File: 2089_bf.cpp * Create

hdu 4960 Another OCD Patient(dp)

Another OCD Patient Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 645    Accepted Submission(s): 238 Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) patient. This mornin

hdu 1501 Zipper (dfs+记忆化搜索)

Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6491    Accepted Submission(s): 2341 Problem Description Given three strings, you are to determine whether the third string can be formed

hdu 4568(状态压缩dp)

题意:一张n*m的网格内每个点有话费,还有若干个宝藏,问一个人要走进去拿走所有宝藏在走出来的最小花费. 思路:看宝藏只有13个直接想到了状压dp[i][j]拿了哪几个前一个为j的最小花费,先bfs+优先队列预处理出最短路,然后记忆化搜索就可. 代码如下: 1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao

HDU 1011 Starship Troopers(树形DP)

Starship Troopers Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 62   Accepted Submission(s) : 12 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description You, the leader of

hdu 1520Anniversary party(简单树形dp)

Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4310    Accepted Submission(s): 1976 Problem Description There is going to be a party to celebrate the 80-th Anniversary of the

HDU 4518 ac自动机+数位dp

吉哥系列故事--最终数 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 304    Accepted Submission(s): 102 Problem Description 在2012年腾讯编程马拉松比赛中,吉哥解决了一道关于斐波那契的题目,这让他非常高兴,也更加燃起了它对数学特别是斐波那契数的热爱.现在,它又在思考一个关于斐波那契