[刷题]ACM ICPC 2016北京赛站网络赛 D - Pick Your Players
2017-05-15 20:06
447 查看
Description
You are the manager of a small soccer team. After seeing the shameless behavior of your team during the match, you are mad at all of the current players. Therefore, you have made a huge decision: put these players on the substitution bench, and buy the entire starting line-up from other teams.You have received a list of available players from your assistant manager. Each player has three properties: Position, Value, and Cost. The Position of a player is one of the four kinds: Goalkeeper, Defender, Midfielder and Forward. The Value shows the ability of the player (the higher, the better), and the Cost is the money you need to spend to buy him.
You are going to pick some players to buy from the list, in order to form the starting line-up. Several rules should be followed:
The starting line-up consists of exactly eleven players.
There should be exactly one Goalkeeper, at least three but at most five Defenders, at least two but at most five Midfielders, and at least one but at most three Forwards in the starting line-up.
There should be exactly one captain in the starting line-up.The captain must be chosen from the eleven players.
The total value of the starting line-up is the sum of the Values of picked players plus the Value of the captain. In another word, the Value of the captain is counted twice.
The total cost of the starting line-up is the sum of the Costs of picked players, which should not exceed the given cost limitation.
Now you have to give a plan to your boss before taking the actual actions. In the plan, you should report three numbers which your boss really interests in: Vt, Ct, N, where Vt is the maximum total value you can get; Ct is the minimum total cost when the total value is Vt; And N is the number of different ways to pick players when the total value is Vt and the total cost is Ct. Since your boss does not care the precise number of N if it is larger than 1,000,000,000, just report N = 1,000,000,000 when that happens.
Note that if two or more ways that pick the same eleven players and are only different in captain chosen, they should be regarded as the same.
Input
There are several test cases in the input.The first line contains an integer T (1 <= T <= 10) – the number of test cases.
For each case:
The first line contains an integer M (11 <= M <= 500) – the number of players on the list.
Then follows M lines, each line contains a string P and two integers V and C (0 <= V <= 1000, 0 <= C <= 1000), separated by a single space, describing the properties of a player. P is the position of the player, which is one of the strings “Goalkeeper”, “Defender”, “Midfielder”, and “Forward”; V is the Value of the player and C is the Cost of the player.
The last line contains an integer L (0 <= L <= 1000) – the cost limitation.
Output
For each test case, output three integers Vt, Ct and N on a single line, separated by a single space. We assure that there is at least one possible way to pick your players.Note
In the sample, you should pick all five Defenders, four Midfielders with Value 178, 20, 64 and 109, one Forward with Value 6, and one of two Goalkeepers with Value 57. The Midfielder with Value 178 should be the captain.Sample
input1 15 Defender 23 45 Midfielder 178 85 Goalkeeper 57 50 Goalkeeper 57 50 Defender 0 45 Forward 6 60 Midfielder 20 50 Goalkeeper 0 50 Midfielder 64 65 Midfielder 109 70 Forward 211 100 Defender 0 40 Defender 29 45 Midfielder 57 60 Defender 52 45 600
output
716 600 2
Key
来自ICPCCamp.Post的题解:题意:你需要买一个足球队(11个球员),每个球员有位置、价值。花费,有以下限制:
位置分为前锋(1-3人)、中腰(2-5)、后卫(3-5)、守门员(1)
每个人有value,总的value 是每个人的value加起来 ,选一个队长,队长的加两次
每个人有个 cost,总花费不能超过给定值
求:最大的 value,相应的最小的 cost,相应的购买方案数(大于1e9输出1e9)
10组数据,500个候选人,value和cost:V and C (0 <= V <= 1000, 0 <= C <= 1000),花费上界:1000
题解:考虑dp(i,cost,j,k,r,w)=(value,way)表示考虑前ii个球员,费用和为cost,选了j个前锋kk个中腰r个后卫w个守门员这个状态,价值和是value,方案数是way。然后按照dp字面意思转移就可以了。然后第一维的ii这里是为了看起来方便,其实是不用开的。
为了方便处理队长,把球员们按照价值从大到小排序,挑的第一个人当队长就可以了。
不太清楚从如果按照题解大到小排序的话选队长为什么一定是对的(虽然它的确是这样),所以我选择从小到大排序,至少这样我会做一点。。。这样的话每个当前运动员都要考虑做一次队长,效率是差一点点。不过即便如此还是没做出来。。。。老是WA,甚至开始怀疑hihocoder上的测试数据是错的(这题有事没事debug了1个月了,老是WA,WA到怀疑人生)。
总这贴这里以后不管了。。。
Code(WA)
#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> #define dfor(i,l,r) for(int i=l;i>=r;--i) using namespace std; typedef long long lld; const int maxn = 1000; const int maxl = 1000000000; const int mg = 1, md = 5, mm = 5, mf = 3; int arr[2][6][6][4][maxn][3]; // G, D, M, F , cost, value/num/captain's value struct member { char P; int V, C; }lst[maxn + 10]; int T, M; lld L; char ipt_tmp[16]; bool cmp(const member &arg1, const member &arg2) { if (arg1.V == arg2.V) return arg1.C < arg2.C; return arg1.V < arg2.V; } int main() { std::ios::sync_with_stdio(false); cin >> T; while (T--) { memset(arr, 0, sizeof(arr)); cin >> M; for (int i = 0; i != M; ++i) { member &now = lst[i]; cin >> ipt_tmp >> now.V >> now.C; now.P = *ipt_tmp; } cin >> L; sort(lst, lst + M, cmp); for (int i = 0; i != M; ++i) { const member &nowp = lst[i]; if (nowp.P == 'G') { // exactly one Goalkeeper dfor(g, mg, 1)dfor(d, md, 0)dfor(m, mm, 0)dfor(f, mf, 0) { int(&predp)[maxn][3] = arr[g - 1][d][m][f]; int(&nowdp)[maxn][3] = arr[g][d][m][f]; if (g + d + m + f > 11) continue; dfor(c, L, nowp.C) { int(&nowc)[3] = nowdp[c]; int(&prec)[3] = predp[c - nowp.C]; if (prec[1] == 0) continue; if (nowc[0] + nowc[2] <= prec[0] + nowp.V + nowp.V) { if (nowc[0] + nowc[2] < prec[0] + nowp.V + nowp.V) { nowc[0] = prec[0] + nowp.V; nowc[1] = prec[1]; } else { if ((nowc[1] += prec[1]) > maxl) { nowc[1] = maxl; } } nowc[2] = nowp.V; } } } if (nowp.V + nowp.V >= arr[1][0][0][0][nowp.C][0] + arr[1][0][0][0][nowp.C][2] && nowp.C < L) { if (nowp.V + nowp.V > arr[1][0][0][0][nowp.C][0] + arr[1][0][0][0][nowp.C][2]) { arr[1][0][0][0][nowp.C][0] = nowp.V; arr[1][0][0][0][nowp.C][1] = 1; arr[1][0][0][0][nowp.C][2] = nowp.V; } else { ++arr[1][0][0][0][nowp.C][1]; } } } else if (nowp.P == 'D') { // at least 3 but at most 5 Defenders dfor(d, md, 1)dfor(g, mg, 0)dfor(m, mm, 0)dfor(f, mf, 0) { int(&predp)[maxn][3] = arr[g][d - 1][m][f]; int(&nowdp)[maxn][3] = arr[g][d][m][f]; if (g + d + m + f > 11) continue; dfor(c, L, nowp.C) { int(&nowc)[3] = nowdp[c]; int(&prec)[3] = predp[c - nowp.C]; if (prec[1] == 0) continue; if (nowc[0] + nowc[2] <= prec[0] + nowp.V + nowp.V) { if (nowc[0] + nowc[2] < prec[0] + nowp.V + nowp.V) { nowc[0] = prec[0] + nowp.V; nowc[1] = prec[1]; } else { if ((nowc[1] += prec[1]) > maxl) { nowc[1] = maxl; } } nowc[2] = nowp.V; } } } if (nowp.V + nowp.V >= arr[0][1][0][0][nowp.C][0] + arr[0][1][0][0][nowp.C][2] && nowp.C < L) { if (nowp.V + nowp.V > arr[0][1][0][0][nowp.C][0] + arr[0][1][0][0][nowp.C][2]) { arr[0][1][0][0][nowp.C][0] = nowp.V; arr[0][1][0][0][nowp.C][1] = 1; arr[0][1][0][0][nowp.C][2] = nowp.V; } else { ++arr[0][1][0][0][nowp.C][1]; } } } else if (nowp.P == 'M') { // at least 2 but at most 5 Midfielders dfor(m, mm, 1)dfor(g, mg, 0)dfor(d, md, 0)dfor(f, mf, 0) { int(&predp)[maxn][3] = arr[g][d][m - 1][f]; int(&nowdp)[maxn][3] = arr[g][d][m][f]; if (g + d + m + f > 11) continue; dfor(c, L, nowp.C) { int(&nowc)[3] = nowdp[c]; int(&prec)[3] = predp[c - nowp.C]; if (prec[1] == 0) continue; if (nowc[0] + nowc[2] <= prec[0] + nowp.V + nowp.V) { if (nowc[0] + nowc[2] < prec[0] + nowp.V + nowp.V) { nowc[0] = prec[0] + nowp.V; nowc[1] = prec[1]; } else { if ((nowc[1] += prec[1]) > maxl) { nowc[1] = maxl; } } nowc[2] = nowp.V; } } } if (nowp.V + nowp.V >= arr[0][0][1][0][nowp.C][0] + arr[0][0][1][0][nowp.C][2] && nowp.C < L) { if (nowp.V + nowp.V > arr[0][0][1][0][nowp.C][0] + arr[0][0][1][0][nowp.C][2]) { arr[0][0][1][0][nowp.C][0] = nowp.V; arr[0][0][1][0][nowp.C][1] = 1; arr[0][0][1][0][nowp.C][2] = nowp.V; } else { ++arr[0][0][1][0][nowp.C][1]; } } } else { // at least 1 but at most 3 Forwards dfor(f, mf, 1)dfor(g, mg, 0)dfor(d, md, 0)dfor(m, mm, 0) { int(&predp)[maxn][3] = arr[g][d][m][f - 1]; int(&nowdp)[maxn][3] = arr[g][d][m][f]; if (g + d + m + f > 11) continue; dfor(c, L, nowp.C) { int(&nowc)[3] = nowdp[c]; int(&prec)[3] = predp[c - nowp.C]; if (prec[1] == 0) continue; if (nowc[0] + nowc[2] <= prec[0] + nowp.V + nowp.V) { if (nowc[0] + nowc[2] < prec[0] + nowp.V + nowp.V) { nowc[0] = prec[0] + nowp.V; nowc[1] = prec[1]; } else { if ((nowc[1] += prec[1]) > maxl) { nowc[1] = maxl; } } nowc[2] = nowp.V; } } } if (nowp.V + nowp.V >= arr[0][0][0][1][nowp.C][0] + arr[0][0][0][1][nowp.C][2] && nowp.C < L) { if (nowp.V + nowp.V > arr[0][0][0][1][nowp.C][0] + arr[0][0][0][1][nowp.C][2]) { arr[0][0][0][1][nowp.C][0] = nowp.V; arr[0][0][0][1][nowp.C][1] = 1; arr[0][0][0][1][nowp.C][2] = nowp.V; } else { ++arr[0][0][0][1][nowp.C][1]; } } } } // DP finished int max_value = -1, min_cost = maxn, sum_num = 0; dfor(g, mg, 1)dfor(d, md, 3)dfor(m, mm, 2)dfor(f, mf, 1) { if (g + d + m + f != 11) continue; dfor(c, L, 0) { int(&now)[3] = arr[g][d][m][f][c]; //if (now[0]) { // cerr << " val: " << now[0] + now[2] << "\tnum: " << now[1] << "\tcost: " << c << '\t'; // cerr << "g: " << g << " d: " << d << " m: " << m << " f: " << f << endl; //} if (now[0] + now[2] > max_value) { max_value = now[0] + now[2]; min_cost = c; sum_num = now[1]; } else if (now[0] + now[2] == max_value) { if (min_cost > c) { min_cost = c; sum_num = now[1]; } else if (min_cost == c) { sum_num += now[1]; } } } } cout << max_value << ' ' << min_cost << ' ' << sum_num << " \n"[T]; } return 0; }
相关文章推荐
- [刷题]ACM/ICPC 2016北京赛站网络赛 第1题 第3题
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 A Simple Job
- hihocoder1386 Pick Your Players(dp)
- HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)
- 北京赛区(2016)网络赛A-The Book List-数据结构+DFS
- hihoCoder 1391 Countries 【预处理+排序+堆】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 C.A Simple Job map<string, map<string, int> > 、字符串单词词组的处理
- 【2016-北京赛区网络赛-I】枚举,贪心,优先队列,优化(导弹,hihocoder 1391)
- HDU5876 补图求最短路 2016ACM ICPC青岛网络赛
- HDU 4041 Eliminate Witches! (ACM ICPC 2011北京赛区网络赛)
- HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)
- HDU 4041 Eliminate Witches! (ACM ICPC 2011北京赛区网络赛)
- 北京赛区(2016)网络赛 A题 The Book List
- hihoCoder 1391 Countries 【预处理+排序+堆】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 The Book List
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 F. Periodic Signal(FFT 优化乘法)
- 2016 大连网络赛 hdu 5876 ACM ICPC(补图求最短路)
- HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)
- hihoCoder 1392 War Chess 【模拟】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)
- hihoCoder 1391 Countries 【预处理+排序+堆】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)