UVALive 5025 Arranging Your Team

Arranging Your Team
Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

Description

Download as PDF

Your country has qualified for the FIFA 2010 South Africa World Cup. As the coach, you have made up the 23 men squad. Now you must select 11 of them as the starters. As is well known, there are four positions in soccer: goalkeeper, defender, midfielder and striker. Your favorite formation is 4-4-2, that is, you should choose 4 defenders, 4 midfielders, 2 strikers, and of course, 1 goalkeeper. As a retired ACMer, you want to write a program to help you make decision. Each person's ability has been evaluated as a positive integer. And what's more, for some special pairs of persons, if the two people are both on the field, there will be an additional effect (positive or negative). Now you should choose the 11 persons to make the total value maximum.

Input

There are multiple test cases, separated by an empty line. The first 23 lines of each test case indicate each person's name Si, ability valueVi, and position. The length of each name is no more than 30, and there are no whitespaces in the names. All the names are different. The ability values are positive integers and no more than 100. The position is one of ``goalkeeper", ``defender", ``midfielder" and ``striker".

Then an integer M indicates that there are M special pairs. Each of the following M lines contains SiSj and Cij, means that if Si and Sj are both on the field, the additional profit is Cij(- 100$ \le$Cij$ \le$100)Si and Sj are different strings, and must be in the previous 23 names. All the (SiSj) pairs are different.

Output

Output one line for each test case, indicating the maximum total ability values, that is, the total ability values of the 11 persons plus the additional effects. If you cannot choose a 4-4-2 formation, output ``impossible" instead.

Sample Input

Buffon 90 goalkeeper 
De_Sanctis 80 goalkeeper 
Marchetti 80 goalkeeper 
Zambrotta 90 defender 
Cannavaro 90 defender 
Chiellini 90 defender 
Maggio 90 defender 
Bonucci 80 defender 
Criscito 80 defender 
Bocchetti 80 defender 
Pirlo 90 midfielder
Gattuso 90 midfielder 
De_Rossi 90 midfielder 
Montolivo 90 midfielder 
Camoranesi 80 midfielder
Palombo 80 midfielder 
Marchisio 80 midfielder 
Pepe 80 midfielder 
Iaquinta 90 striker 
Di_Natale 90 striker 
Gilardino 80 striker 
Quagliarella 80 striker 
Pazzini 80 striker 
1 
Pirlo Quagliarella 50 

ZhangSan01 50 goalkeeper
ZhangSan02 50 defender 
ZhangSan03 50 defender 
ZhangSan04 50 defender 
ZhangSan05 50 defender 
ZhangSan06 50 defender 
ZhangSan07 50 defender 
ZhangSan08 50 defender 
ZhangSan09 50 defender 
ZhangSan10 50 defender 
ZhangSan11 50 defender 
ZhangSan12 50 defender 
ZhangSan13 50 defender 
ZhangSan14 50 defender 
ZhangSan15 50 defender 
ZhangSan16 50 midfielder
ZhangSan17 50 midfielder
ZhangSan18 50 midfielder
ZhangSan19 50 midfielder
ZhangSan20 50 midfielder
ZhangSan21 50 midfielder
ZhangSan22 50 midfielder
ZhangSan23 50 midfielder
0

Sample Output

1030 
impossible

题解及代码:


/*
参考了一下别人的代码,才写出来的,感觉他的代码很优美,
简洁清爽的感觉。
附上网址:http://alwa.name/blog/?p=47
*/

#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <string>
using namespace std;
int ans=0;
map<string,int>M;
map<string,int>N;
int vis[30];
int add[25][25];

struct node
{
    int d;
    int en;
}z[25];

void solve(int src,int de,int mi,int st,int go)
{
    if(de==4&&mi==4&&st==2&&go==1)
    {
        int sum=0;
        for(int i=0;i<23;i++)
        if(vis[i])
        {
            sum+=z[i].d;
            for(int j=0;j<23;j++)
            if(vis[j])
            {
                sum+=add[i][j];
            }
        }
        if(ans<sum) ans=sum;
        return;
    }

    for(int i=src;i<23;i++)
    if(!vis[i])
    {
        if(z[i].en==1&&de==4) continue;
        if(z[i].en==2&&mi==4) continue;
        if(z[i].en==3&&st==2) continue;
        if(z[i].en==4&&go==1) continue;
        vis[i]=1;
        if(z[i].en==1) solve(i+1,de+1,mi,st,go);
        if(z[i].en==2) solve(i+1,de,mi+1,st,go);
        if(z[i].en==3) solve(i+1,de,mi,st+1,go);
        if(z[i].en==4) solve(i+1,de,mi,st,go+1);
        vis[i]=0;
    }
}


int main()
{
    string s="defender";
    N[s]=1;
    s="midfielder";
    N[s]=2;
    s="striker";
    N[s]=3;
    s="goalkeeper";
    N[s]=4;
    string l,r;
    int d,n;
    while(cin>>l>>d>>r)
    {
        M.clear();
        M[l]=0;
        z[0].d=d;
        z[0].en=N[r];
        for(int i=1;i<23;i++)
        {
            cin>>l>>d>>r;
            M[l]=i;
            z[i].d=d;
            z[i].en=N[r];
        }
        int num_de=0,num_mi=0,num_st=0,num_go=0;
        for(int i=0;i<23;i++)
        {
            if(z[i].en==1) num_de++;
            if(z[i].en==2) num_mi++;
            if(z[i].en==3) num_st++;
            if(z[i].en==4) num_go++;
        }
        scanf("%d",&n);
        memset(add,0,sizeof(add));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
        {
            cin>>l>>r>>d;
            add[M[l]][M[r]]=d;
        }

        if(num_de<4||num_mi<4||num_st<2||num_go<1)
        {
            printf("impossible\n");
            continue;
        }

        ans=-100000;//初始化为负数,最后ans可能为负数,wa了一次
        solve(0,0,0,0,0);
        printf("%d\n",ans);
    }
    return 0;
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值