您的位置:首页 > 其它

HDU 3720 Arranging Your Team

2015-08-04 19:25 399 查看
题目链接: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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: