篮球校赛(状压dp)

篮球校赛

题目描述

 

JWJU注重培养学生的“唱,跳,rap,篮球”能力。于是每年JWJU都会举办篮球校赛,来给同学们一个切磋篮球技术的平台。校赛冠军的奖励是看wls女装一次,为了这个目标,大家都努力训练,希望自己能看到wls女装。

教练mymy手下有 nn 名队员,现在他要挑选 55 人组成一个篮球队来参赛。众所周知,一个篮球队伍有五个不同的位置(控球后卫,得分后卫,小前锋,大前锋,中锋),现在教练mymy给出每名队员在每个位置的能力。

注:如果一个队员作为控球后卫出战,则他只能发挥他的控球后卫的能力值。(其他位置类似)

教练mymy想让你帮忙选择出 55 名队员,分别放置在队伍中的不同位置。求他们组成的队伍的最大能力值之和。

 
 

输入描述

 

输出第一行包含一个正整数 nn (5 \le n \le 10^{5}5n105)。

扫描二维码关注公众号,回复: 6943555 查看本文章

接下来包含 nn 行,每行包含 55 个正整数,描述每个队员在每个位置的能力值。每项能力值的取值范围都在 [1,10^{9}][1,109]。

输出描述

 

输出一行一个正整数代表组成的队伍的最大能力值之和。

样例输入 1 

5
10 11 12 15 10
10 15 12 11 10
15 10 15 15 15
19 20 114000 10 300
14 10 155 200 469

样例输出 1

114514

题目思路:
其实本题也可以直接排序后dfs做,因为最后选出的五个人一定有一项能力是排名前五的。

dp[i][j]表示前i行五个位置状态为j的最大能力值。

  if(!(j>>k&1))//如果状态为j的第k位为空
    dp[i][j|(1<<k)] = max(dp[i][j|(1<<k)],dp[i-1][j]+a[i][k]);//(状态转移)

 最后答案为dp[n][1<<5-1].

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
ll dp[100100][32],n,a[100010][5];
int main()
{
    cin>>n;
    for(int i = 1;i<=n;i++)
        for(int j = 0;j<5;j++)
            scanf("%d",&a[i][j]);
    for(int i = 1;i<=n;i++)
    {
        for(int j = 0;j<32;j++)
            dp[i][j] = dp[i-1][j];    
        for(int j = 0;j<32;j++)
            for(int k = 0;k<5;k++)
                if(!(j>>k&1))
                    dp[i][j|(1<<k)] = max(dp[i][j|(1<<k)],dp[i-1][j]+a[i][k]);
    }
    cout<<dp[n][31];
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/loganacmer/p/11296928.html