HDU 3720 Arranging Your Team

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3720


题意:有4种一共23球员,需要选出10个球员组成4-4-2 阵容和1个守门员,每个球员都有能力值,以及2个球员之间可能会有combin额外增加或者减少能力值


思路:一开始就想到了dfs,但是很蠢的选择了递推到11层,每层从23个球员进行挑选的方式,后来看了题解……进行了剪枝,每个球员只有选择和不选择2种情况,一共23层,每层只有2个分支,要注意的是combin可能导致res为负,初始化要注意(看了下自己写的代码蠢到无法直视)



#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#define inf 0x3f3f3f3f
using namespace std;

struct Hum
{
    int val,k;
    string name;
}s[50];
char ball[30];
int kind[5],num[5]={1,4,4,2},com[30][30];vis[50],kvis[5],res;

void dfs(int n,int m,int abi)
{
    if (n==11)
    {
        res=max(abi,res);
        return;
    }
    if (m>=23) return;
    dfs(n,m+1,abi);
    if (kvis[s[m].k]<num[s[m].k])
    {
      int change=0;
      vis[m]=1;
      kvis[s[m].k]++;
      for (int i=0;i<26;i++)
      {
          if (vis[i] && com[m][i]!=0)
          {
              change+=com[m][i];
          }
      }
      abi=abi+s[m].val+change;
      dfs(n+1,m+1,abi);
      abi=abi-s[m].val-change;
      kvis[s[m].k]--;
      vis[m]=0;
    }
}

int main()
{
    int t,n;
    while (cin>>s[0].name)
    {
        scanf("%d %s",&s[0].val,&ball);
        if (ball[0]=='g')
        {
            kind[0]++;
            s[0].k=0;
        }
        else if (ball[0]=='d')
        {
            kind[1]++;
            s[0].k=1;
        }
        else if (ball[0]=='m')
        {
            kind[2]++;
            s[0].k=2;
        }
        else if (ball[0]=='s')
        {
            kind[3]++;
            s[0].k=3;
        }
        res=-inf;
        memset(com,0,sizeof(com));
        memset(vis,0,sizeof(vis));
        memset(kvis,0,sizeof(kvis));
         memset(kind,0,sizeof(kind));
       for (int i=1;i<23;i++)
       {
           int tem;
           cin>>s[i].name;
           scanf("%d %s",&s[i].val,&ball);
           if (ball[0]=='g')
           {
                kind[0]++;
                s[i].k=0;
           }
           else if (ball[0]=='d')
           {
                kind[1]++;
                s[i].k=1;
           }
           else if (ball[0]=='m')
           {
                kind[2]++;
                s[i].k=2;
           }
           else if (ball[0]=='s')
           {
                kind[3]++;
                s[i].k=3;
           }

       }
       scanf("%d",&n);
       for (int i=0;i<n;i++)
       {
           string x,y;
           int xx,yy,tem;
           cin>>x>>y>>tem;
           for (int j=0;j<23;j++)
           {//
               if (x==s[j].name) xx=j;
               if (y==s[j].name) yy=j;//cout<<s[j].name<<":"<<y<<endl;
           }
          com[xx][yy]=tem;
          com[yy][xx]=tem;
       }
       if (kind[0]<1 || kind[1]<4 || kind[2]<4 || kind[3]<2)
       {
           cout<<"impossible"<<endl;
           continue;
       }
       dfs(0,0,0);
       cout<<res<<endl;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值