搜索-hdu-3720-Arranging Your Team

来源:互联网 发布:yy挂号软件 编辑:程序博客网 时间:2024/05/08 03:58

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3720

题目大意:

有23个人,告诉每个人的名字,能力值,以及踢球的位置。要求选出1个守门员,2个前锋,4个中场,4个后卫。给m个关系,该关系的两个人如果同时在场,就会得到相应的分数值va(注意va可以为负值)。求怎样安排使得在场的人总价值最大。

解题思路:

先处理出每种位置的人分布,然后枚举是哪几个人,凑成后更新总价值即可。注意va可能为负数。

代码:

#include<iostream>#include<cmath>#include<cstdio>#include<sstream>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#include<ctime>#include<bitset>#define eps 1e-6#define INF 0x3f3f3f3f#define PI acos(-1.0)#define ll __int64#define LL long long#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#define M 1000000007#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define Maxn  30map<string,int>nameid;vector<int>pos[5]; //pos[i]保存位置i的人员分布map<string,int>posid; //位置的标号int va[Maxn],add[Maxn][Maxn],ans;bool vis[Maxn];int Cal(){    int res=0;    for(int i=1;i<=23;i++) //已选了哪些人        if(vis[i])            res+=va[i];    for(int i=1;i<=23;i++) //人之间关系的相互影响        for(int j=i+1;j<=23;j++)        {            if(vis[i]&&vis[j])            {                res=res+add[i][j];            }        }    return res;}void dfs4(int num,int cur){    if(num==4)    {        ans=max(ans,Cal()); //已全部选完了        return ;    }    for(int i=cur;i<pos[4].size();i++) //从下一个开始选    {        vis[pos[4][i]]=true;        dfs4(num+1,i+1);        vis[pos[4][i]]=false;    }}void dfs3(int num,int cur){    if(num==4)    {        dfs4(0,0);        return ;    }    for(int i=cur;i<pos[3].size();i++)    {        vis[pos[3][i]]=true;        dfs3(num+1,i+1);        vis[pos[3][i]]=false;    }}void dfs2(int num,int cur){    if(num==2)    {        dfs3(0,0);        return ;    }    for(int i=cur;i<pos[2].size();i++)    {        vis[pos[2][i]]=true;        dfs2(num+1,i+1);        vis[pos[2][i]]=false;    }}void dfs1(int num,int cur){    if(num==1)    {        dfs2(0,0);        return ;    }    for(int i=cur;i<pos[1].size();i++)    {        vis[pos[1][i]]=true;        dfs1(num+1,i+1);        vis[pos[1][i]]=false;    }}int main(){    posid["goalkeeper"]=1; //书名对应标号    posid["striker"]=2;    posid["midfielder"]=3;    posid["defender"]=4;    string name,job;    while(cin>>name)    {        nameid.clear();        for(int i=1;i<=4;i++) /            pos[i].clear();        memset(add,0,sizeof(add));        nameid[name]=1;        scanf("%d",&va[1]);        cin>>job;        pos[posid[job]].push_back(1); //该职业新增一人        for(int i=2;i<=23;i++)        {            cin>>name>>va[i]>>job;            nameid[name]=i; //人的标号            pos[posid[job]].push_back(i);//先找到该位置标号,然后添加该人        }        int m;        scanf("%d",&m);        while(m--)        {            string name2;            int tmp;            cin>>name>>name2>>tmp; //人之间的关系值            add[nameid[name]][nameid[name2]]=tmp;            add[nameid[name2]][nameid[name]]=tmp;        }        if(pos[1].size()<1||pos[2].size()<2||pos[3].size()<4||pos[4].size()<4)        {            printf("impossible\n");            continue;        }        ans=-INF;        memset(vis,false,sizeof(vis));        dfs1(0,0);        printf("%d\n",ans);    }   return 0;}