Topcoder SRM 152 Div2 1000(状态压缩呀)

本文介绍了一种用于优化团队成员组合的算法,旨在通过数学模型找到最佳的团队成员搭配方案,以确保团队内部的良好协作。该算法考虑了成员间的相互关系,并以最大化团队协作效率为目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem Statement

 A large company is trying to put together a team of people to work on some task. In order for any team to work well, the people involved must be able to get along with each other. The managers at the company have put together a list of potential candidates for the team, and have assigned a number to each pair of candidates, representing how well those two people get along. The more positive a number, the better two people get along, while the more negative a number, the more they dislike each other. The candidates are all well qualified, so at this point the only consideration is how well the team will get along. You are to pick which candidates to put on the team to maximize the sum of the numbers assigned to all of the pairs of people on the team. You will be given a vector <string>, people, each of whose elements represents a single candidate, and an int, teamSize, representing the number of people to place on the team. Each element of people will be formatted as (quotes and angle brackets for clarity only):
"<name> <number0> <number1> <number2> ... <numberN>"
In other words, the element will start with the person's name, which will consist only of uppercase letters ('A'-'Z'), and will be followed by a single space delimited list of integers. The jth integer in the ith element will represent how well person i gets along with person j and will be the same as the ith integer in the jth element. The ith integer in the ith element will always be 0 (how well a person gets along with himself). Your task is to return a vector <string>, which contains the names of the people to put on the team (if more than one person on the team has the same name, that name must be in the returned vector <string> once for every member of the team with that name). The returned vector <string> should be sorted in ascending order. To make things simpler, there will only be one team which causes the maximum sum.

For example, if teamSize = 3 and people =
{"ALICE 0 1 -1 3",
 "BOB 1 0 2 -4",
 "CAROL -1 2 0 2",
 "DAVID 3 -4 2 0"}
There are four ways to create a team with 3 people. They give rise to the following sums:
ALICE, BOB, and CAROL: 1 + -1 + 2 = 2
ALICE, BOB, and DAVID: 1 + 3 + -4 = 0
ALICE, CAROL, and DAVID: -1 + 3 + 2 = 4
BOB, CAROL, and DAVID: 2 + -4 + 2 = 0
Of these, ALICE, CAROL and DAVID gives the highest sum, so your method would return {"ALICE","CAROL","DAVID"}.

Definition

 
Class:PickTeam
Method:pickPeople
Parameters:int, vector <string>
Returns:vector <string>
Method signature:vector <string> pickPeople(int teamSize, vector <string> people)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):64

Constraints

-people will contain between 3 and 20 elements, inclusive.
-Each element of people will contain between 7 and 50 characters, inclusive.
-teamSize will be between 2 and the number of elements in people - 1, inclusive.
-Each element of people will be formatted as a sequence of uppercase letters ('A'-'Z'), followed by a single space delimited list of integers.
-Each element of people will contain the same number of integers as there are elements in people.
-Each integer in each element of people will be between -999 and 999, inclusive and will not have any extra leading zeros.
-The ith integer of the jth element of people will be the same as the jth integer of the ith element of people.
-The ith integer of the ith element will always be 0.
-There will be only 1 way to make a team with the highest sum.

Examples

0) 
 
3
{"ALICE 0 1 -1 3",
 "BOB 1 0 2 -4",
 "CAROL -1 2 0 2",
 "DAVID 3 -4 2 0"}
Returns: { "ALICE",  "CAROL",  "DAVID" }
The example from above.
1) 
 
2
{"ALICE 0 1 -1 3",
 "BOB 1 0 2 -4",
 "CAROL -1 2 0 2",
 "DAVID 3 -4 2 0"}
Returns: { "ALICE",  "DAVID" }
 
2) 
 
2
{"A 0 -2 -2","B -2 0 -1","C -2 -1 0"}
Returns: { "B",  "C" }
 
3) 
 
13
{"A 0 2 8 7 1 -4 -3 1 8 2 8 2 1 -3 7 1 3 9 -6 -5",
 "A 2 0 0 7 -7 -5 8 -8 -9 -9 6 -9 -4 -8 8 1 7 0 3 3",
 "A 8 0 0 -5 -5 -7 1 -3 1 9 -6 6 1 5 6 -9 8 6 -8 -8",
 "A 7 7 -5 0 7 -5 3 9 8 3 -6 -5 -5 2 -6 2 -2 -1 -2 8",
 "B 1 -7 -5 7 0 7 -2 -9 3 7 0 -2 1 1 -9 -3 -2 2 1 -2",
 "B -4 -5 -7 -5 7 0 4 8 6 0 -1 4 1 -2 -9 4 0 -7 6 -2",
 "B -3 8 1 3 -2 4 0 8 -1 1 -2 -7 5 0 -6 9 0 -3 1 3",
 "B 1 -8 -3 9 -9 8 8 0 0 -2 5 0 5 8 3 5 2 4 5 4",
 "C 8 -9 1 8 3 6 -1 0 0 8 -3 8 -6 -4 7 -4 1 -5 5 4",
 "C 2 -9 9 3 7 0 1 -2 8 0 -9 -6 6 5 -8 -3 -8 2 2 4",
 "C 8 6 -6 -6 0 -1 -2 5 -3 -9 0 2 7 8 2 -6 -4 -6 4 4",
 "C 2 -9 6 -5 -2 4 -7 0 8 -6 2 0 0 -3 6 7 -1 2 -4 -2",
 "D 1 -4 1 -5 1 1 5 5 -6 6 7 0 0 -7 -4 8 -6 -3 4 -6",
 "D -3 -8 5 2 1 -2 0 8 -4 5 8 -3 -7 0 7 -3 5 -8 5 1",
 "D 7 8 6 -6 -9 -9 -6 3 7 -8 2 6 -4 7 0 9 -5 -5 -8 3",
 "D 1 1 -9 2 -3 4 9 5 -4 -3 -6 7 8 -3 9 0 -2 -7 8 -7",
 "E 3 7 8 -2 -2 0 0 2 1 -8 -4 -1 -6 5 -5 -2 0 6 0 5",
 "E 9 0 6 -1 2 -7 -3 4 -5 2 -6 2 -3 -8 -5 -7 6 0 4 8",
 "E -6 3 -8 -2 1 6 1 5 5 2 4 -4 4 5 -8 8 0 4 0 1",
 "E -5 3 -8 8 -2 -2 3 4 4 4 4 -2 -6 1 3 -7 5 8 1 0"}
Returns: { "A",  "A",  "B",  "B",  "B",  "B",  "C",  "C",  "C",  "D",  "D",  "D",  "E" }


就状态压缩呀。就20个人。


//Hello. I'm Peter.
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define peter cout<<"i am peter"<<endl
#define input freopen("data.txt","r",stdin)
#define randin srand((unsigned int)time(NULL))
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define gsize(a) (int)a.size()
#define len(a) (int)strlen(a)
#define slen(s) (int)s.length()
#define pb(a) push_back(a)
#define clr(a) memset(a,0,sizeof(a))
#define clr_minus1(a) memset(a,-1,sizeof(a))
#define clr_INT(a) memset(a,INT,sizeof(a))
#define clr_true(a) memset(a,true,sizeof(a))
#define clr_false(a) memset(a,false,sizeof(a))
#define clr_queue(q) while(!q.empty()) q.pop()
#define clr_stack(s) while(!s.empty()) s.pop()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define dep(i, a, b) for (int i = a; i > b; i--)
#define repin(i, a, b) for (int i = a; i <= b; i++)
#define depin(i, a, b) for (int i = a; i >= b; i--)
#define pi 3.1415926535898
#define eps 1e-6
#define MOD 1000000007
#define MAXN 210000
#define N 500
#define M 30
int n,twopow[M];
vector<int>Get_candidate(int x){
    vector<int>res;res.clear();
    int t;
    repin(i,1,n){
        t=x&twopow[i-1];
        if(t) res.pb(i);
    }
    return res;
}
string name[M];
int rel[M][M];
int stringtoint(string s){
    bool negative;
    if(s[0]=='-')
    {
        negative=true;
        s.erase(0,1);
    }
    else negative=false;
    int len=slen(s);
    int res=0,ten=1;
    depin(i,len-1,0){
        res+=ten*(s[i]-'0');
        ten*=10;
    }
    if(negative) res=-res;
    return res;
}
class PickTeam
{
public:
    vector <string> pickPeople(int teamSize, vector <string> people)
    {
        twopow[0]=1;
        repin(i,1,28){
            twopow[i]=twopow[i-1]<<1;
        }
        n=gsize(people);
        string row,s;
        rep(i,0,n){
            row=people[i];
            istringstream ss(row);
            int t=-1;
            while(ss>>s){
                t+=1;
                if(t==0) name[i+1]=s;
                else rel[i+1][t]=stringtoint(s);
            }
        }
        int limit=(1<<n)-1;
        vector<int>candidate,vecres;
        vecres.clear();
        int res=-INT;
        repin(i,0,limit)
        {
            candidate=Get_candidate(i);
            int len=gsize(candidate);
            if(len==teamSize){
                int t=0;
                rep(i1,0,len){
                    rep(i2,i1+1,len){
                        t+=rel[candidate[i1]][candidate[i2]];
                    }
                }
                if(t>res)
                {
                    res=t;
                    vecres=candidate;
                }
            }
        }
        int len=gsize(vecres);
        vector<string>ans;
        ans.clear();
        rep(i,0,len){
            ans.pb(name[vecres[i]]);
        }
        sort(ans.begin(),ans.end());
        return ans;
    }
};





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值