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> <pos 1> <CA 1> <PA 1> <pos 2> <CA 2> <PA 2> . . . <pos num><CA num><PA num>
Here:
<SquadNum> denotes the player’s unique squad number (between 1 and 99, inclusive).
<PositionNum> denotes the number of positions he preferred.
<pos 1> <pos 2> . . . <pos num> are strings chosen in {GK, DF, MF, ST},denoting all his preferred positions.
<CA i> denotes his CA at <pos i>.
<PA i> denotes his PA at <pos i>.
(0<=|P A i|,|C A i|<=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:
<SquadNum A> <SquadNum B > Like/Dislike <value>
Here:
<SquadNum A> denotes Player A’s Squad Number.
<SquadNum B> 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


思路:先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");
    }
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值