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:

  1. The starting line-up consists of exactly eleven players.

  2. 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.

  3. There should be exactly one captain in the starting line-up.The captain must be chosen from the eleven players.

  4. 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.

  5. 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

input

1
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北京赛站网络赛 D - Pick Your Players的更多相关文章

  1. [刷题]ACM/ICPC 2016北京赛站网络赛 第1题 第3题

    第一次玩ACM...有点小紧张小兴奋.这题目好难啊,只是网赛就这么难...只把最简单的两题做出来了. 题目1: 代码: //#define _ACM_ #include<iostream> ...

  2. HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)

    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: ...

  3. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛D-80 Days--------树状数组

    题意就是说1-N个城市为一个环,最开始你手里有C块钱,问从1->N这些城市中,选择任意一个,然后按照顺序绕环一圈,进入每个城市会有a[i]元钱,出来每个城市会有b[i]个城市,问是否能保证经过每 ...

  4. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 80 Days(尺取)题解

    题意:n个城市,初始能量c,进入i城市获得a[i]能量,可能负数,去i+1个城市失去b[i]能量,问你能不能完整走一圈. 思路:也就是走的路上能量不能小于0,尺取维护l,r指针,l代表出发点,r代表当 ...

  5. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛-B:Tomb Raider(二进制枚举)

    时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Lara Croft, the fiercely independent daughter of a missing adv ...

  6. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛

    题意:到一个城市得钱,离开要花钱.开始时有现金.城市是环形的,问从哪个开始,能在途中任意时刻金钱>=0; 一个开始指针i,一个结尾指针j.指示一个区间.如果符合条件++j,并将收益加入sum中( ...

  7. hihoCoder #1831 : 80 Days-RMQ (ACM/ICPC 2018亚洲区预选赛北京赛站网络赛)

    水道题目,比赛时线段树写挫了,忘了RMQ这个东西了(捞) #1831 : 80 Days 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 80 Days is an int ...

  8. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 A、Saving Tang Monk II 【状态搜索】

    任意门:http://hihocoder.com/problemset/problem/1828 Saving Tang Monk II 时间限制:1000ms 单点时限:1000ms 内存限制:25 ...

  9. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 B Tomb Raider 【二进制枚举】

    任意门:http://hihocoder.com/problemset/problem/1829 Tomb Raider 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 L ...

随机推荐

  1. Atitit.获取某个服务 网络邻居列表 解决方案

    Atitit.获取某个服务 网络邻居列表 解决方案 原理,带入某个ip扫描从0---255 很快,多线程几秒就可以出来. 使用CountDownLatch来join线程.. 返回  [{ " ...

  2. 真正理解红黑树,真正的(Linux内核里大量用到的数据结构,且常被二货问到)

    作为一种数据结构.红黑树可谓不算朴素.由于各种宣传让它过于神奇,网上搜罗了一大堆的关于红黑树的文章,不外乎千篇一律,介绍概念,分析性能,贴上代码,然后给上罪恶的一句话.它最坏情况怎么怎么地...    ...

  3. 详解Java中格式化日期的DateFormat与SimpleDateFormat类

    DateFormat其本身是一个抽象类,SimpleDateFormat 类是DateFormat类的子类,一般情况下来讲DateFormat类很少会直接使用,而都使用SimpleDateFormat ...

  4. 斑马Zebra ZPLII指令集中文说明解释

      我们最常用的斑马(Zebra)条码打印机,应用ZPLII命令来控制打印,说明书中有每条指令的详细说明及相关示例,下面是各指令的中文释义: ^A 对Zebra内置点阵字体缩放 ^A(可缩放/点阵字体 ...

  5. linux 从百度网盘下载文件的方法

    linux 从百度网盘下载文件的方法 发表于2015 年 月 日由shenwang 方法1.wget wget是在Linux下开发的开放源代码的软件,作者是Hrvoje Niksic,后来被移植到包括 ...

  6. make命令用法--转

    转自:http://www.techug.com/make 代码变成可执行文件,叫做编译(compile):先编译这个,还是先编译那个(即编译的安排),叫做构建(build). Make是最常用的构建 ...

  7. DMA—直接存储区访问

    本章参考资料:< STM32F4xx 中文参考手册> DMA 控制器章节.学习本章时,配合< STM32F4xx 中文参考手册> DMA 控制器章节一起阅读,效果会更佳,特别是 ...

  8. 字符串操作:int 转 string

    strstream ss; string ch; ss<<i; ss>>ch;

  9. SOCK_RAW编程

    TCP(SOCK_STREAM)和UDP套接口(SOCK_DGRAM)可以满足大部分需求,但要获取底层协议内容就需要原始套接字.相比前两者,SOCK_RAW具有如下优点: 1)使用原始套接字可以读写I ...

  10. strspn&strcspn

    size_t strspn (const char *s,const char * accept); strspn返回s中第一个不在accept中出现过的字符下标. Returns an intege ...