CodeForces 1316E Team Building

Description

你需要组建一支排球队。为了组织一支排球队,你需要为队伍里的 $p$ 个不同的位置,从 $n$ 个人中选出 $p$ 个人,且每个位置上都恰好有一个人。另外还需要从剩下的人中选出恰好 $k$ 个人作为观众。

对于第 $i$ 个人,已知他作为观众时能为队伍增加 $a_i$ 点力量,还有他在队伍的第 $j$ 个位置上时能为队伍增加 $s_{i,j}$ 点力量。

请问这只排球队力量的最大值是多少?

Solution

看到 $p$ 很小,考虑状态压缩 DP。

这里先把每个人按照 $a_i$ 降序排序。

设想,对于一个状态 $f_{i, s}$,$s$ 是一个 $p$ 位二进制数,表示队伍的选择情况,当前这个 $i$ 会不会被选进观众呢?

这里用到一个贪心,如果 $i \le \operatorname{CountBit}(s) + k$,那么,我们就会把 $i$ 选到观众里面去。

这很好理解,原本应该是选前 $k$ 个当观众,但是有 $\operatorname{CountBit}(s)$ 个已经被选到队伍里面去了,所以我们把限制往后移这么多位。

接下来,考虑把 $i$ 弄成队员。我们枚举一个 $s$ 包含的位置 $t$,试图把 $i$ 放进去,那么就要用 $f_{i-1, s \oplus 2^t}$ 来更新 $f_{i, s}$。

这题作为状态压缩 DP 还是比较好实现的,时间复杂度 $\mathcal O(n \cdot 2^p)$,具体细节可以看代码。代码中用 $j$ 代替了 $s$。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 5, P = 130;
struct people
{
    LL a, s[7];
    bool operator < (const people &oth) const { return a > oth.a; }
} peo[N];
int n, p, k;
inline int CountBit(int x)
{
    int res = 0;
    while(x) res++, x &= x - 1;
    return res;
}
LL f[N][P];
int main()
{
    scanf("%d %d %d", &n, &p, &k);
    for(int i = 1; i <= n; i++) scanf("%lld", &peo[i].a);
    for(int i = 1; i <= n; i++)
        for(int j = 0; j < p; j++)
            scanf("%lld", &peo[i].s[j]);
    sort(peo + 1, peo + n + 1);
    int full = 1 << p;
    memset(f, -0x3f, sizeof f);
    f[0][0] = 0;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 0; j < full; j++)
        {
            int cnt = CountBit(j);
            f[i][j] = f[i - 1][j];
            if(i <= cnt + k) f[i][j] = max(f[i][j], f[i - 1][j] + peo[i].a);
            for(int t = 0; t < p; t++) if(j >> t & 1)
                f[i][j] = max(f[i][j], f[i - 1][j ^ (1 << t)] + peo[i].s[t]);
        }
    }
    printf("%lld\n", f[n][full - 1]);
    return 0;
}

原文地址:https://www.cnblogs.com/syksykCCC/p/CF1316E.html

时间: 2024-12-29 12:38:27

CodeForces 1316E Team Building的相关文章

BZOJ 4742: [Usaco2016 Dec]Team Building

4742: [Usaco2016 Dec]Team Building Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 21  Solved: 16[Submit][Status][Discuss] Description Every year, Farmer John brings his NN cows to compete for "best in show" at the state fair. His arch -rival, F

codeforces 757F Team Rocket Rises Again

链接:http://codeforces.com/problemset/problem/757/F 正解:灭绝树. mdzz倍增lca的根节点深度必须是1..我因为这个错误调了好久. 我们考虑先求最短路,求完最短路以后,我们就能对原来的无向图构造一个DAG.当我们构造完DAG以后,我们要求的东西已经很明显.那就是删掉一个点以后,最多有多少个点与S不连通.那么,我们按照套路,将DAG跑一遍拓扑排序,建出灭绝树.然后求出除了S点以外的最大size就行了. 1 //It is made by wfj_

codeforces 932E Team Work

codeforces 932E 题目描述 求\(\sum_{i=1}^{n}{(^n_i)i^k}\space mod\space10^9+7\) 思路 本题\(n\)的范围很大\((n\le10^9)\),但\(k\)在可接受的范围内\((k\le5000)\),我们可以尝试从\(k\)入手. 构造\((1+x)^n=\sum_{i=0}^n{(^n_i)x^i}\) 对等式两边求导并同乘\(x\),得 \[ nx(1+x)^{n-1}=\sum_{i=1}^n\big(^n_i\big)ix

Codeforces 932E Team Work 数学

Team Work 发现网上没有我这种写法.. i ^ k我们可以理解为对于每个子集我们k个for套在一起数有多少个. 那么我们问题就变成了 任意可重复位置的k个物品属于多少个子集. 然后我们枚举k个物品所占位置的个数 i , 然后需要计算有多少种方案能把k个不同物品放入i个桶中. 这个东西可以用dp[ i ][ j ] 表示 i 个物品放入 j 个桶中的方案数. dp[ i ][ j ] = dp[ i - 1 ][ j ] * j + dp[ i - 1 ][ j - 1 ] * j 然后就

BZOJ4742 : [Usaco2016 Dec]Team Building

如果我们将两个人拥有的牛混在一起,并按照战斗力从小到大排序,同时把第一个人选的牛看成$)$,第二个人选的牛看成$($的话,那么我们会发现一个合法的方案对应了一个长度为$2k$的括号序列. 于是DP即可,$f[i][j][k]$表示考虑了前$i$头牛,目前选了$j$个左括号,括号序列的前缀和为$k$的方案数. 时间复杂度$O(nk^2)$. #include<cstdio> #include<algorithm> const int N=2010,M=13,P=1000000009;

CodeForces - 401C Team(简单构造)

题意:要求构造一个字符串,要求不能有连续的两个0在一起,也不能有连续的三个1在一起. 分析: 1.假设有4个0,最多能构造的长度为11011011011011,即10个1,因此若m > (n + 1) * 2则肯定不能构造成功. 2.假设有4个0,则至少有3个1,若小于3个,则会有两个连续的0在一起,所以n > m + 1则肯定不能构造成功. 3.当n==m+1时,一定是01串. 4.当m>=n时,应以1为开头构造,根据m和n的个数决定放1个1还是2个连续的1. #include<

CodeForces 490A Team Olympiad

题意: 编号为1.2.3的同学分成一组  问  最多形成多少组  并输出方案 思路: 模拟3个栈暴力 代码: #include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<map> #include<set> #include<vector> #include<queu

scrum站立会议介绍

什么是站立会议? 站立会议是敏捷软件开发方法论Scrum的相关技术之一,亦可称之为Scrum的最佳实践.具体形式为每天的同一时间,一个敏捷开发团队的所有成员面对面站在一起,进行一个为期15~20分钟的短会.在会议上,每个人要依次回答以下三个问题: 1)从上次站立会议到现在,你完成了什么? 2)从现在到下次站立会议,你将要做什么? 3)你遇到什么阻碍,需要其它人如何帮你? 站立会议的意义和功能是什么? 1)创造团队成员相互沟通的条件,了解彼此的工作进展和工作成效: 2)可让项目经理及时发现阻碍项目

几张图片总结我的2015年

经过一年多的摇号,自助商品房终于中签,年初,房子选型. ? 当时还是一个大坑. ? 现场选房,在1000多号中排325号,基本上还占据着选择的主动权. ? 2015MVP Open Day,SQLServer方向的就我们两个人,还记得当时大家聚在一起针对微软的各种吐槽. ? 当时三个活动赶上一起了,选房,open day和Daimler年会,就跟赶场子一样. ? 此后的三波年会,最好的还是金融的年会. ? 大家都在聊着2014年的回忆. ? 于是我一直还是那只打不死的小强. ? 2015年公司给