CodeForce 1133E - K Balanced Teams (dp)

题目链接:https://codeforces.com/contest/1133/problem/E

题目大意:有n个人每个人对应一个值ai,要求组成至少一个,至多k个队伍,且队伍内的人权值差最大不超过5,问此时在队伍中的最多队员数

先对数组从小到大排个序

假设dp[i][j]表示当前将第i个人作为新的队伍的第一个人,且此时有j个非空队伍的状态对应的最大在队伍里的队员数量

转移方向:

1.跳过第i个,直接转移到dp[i+1][j]

2,第i个单独形成一个新的队列 这个地方需要贪心地想一下,一旦形成了一个新的队列,题目的要求又没有规定必须要k个非空,所以一旦形成一个新的队伍,就尽可能多得往这个队里插入队员是最好的

记录cnt[i]表示一旦选第i个选手作为这个队中能力最低的,这个队最多可以由多少人

dp[i][j]+cnt[i] 可以转移到 dp[i+cnt[i]][j+1]

最后的答案就是max ( dp[i][j] )

比较骚的写法是 dp[n][m] (下标从0开始)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5005;
const int inf=99999999;
int a[maxn];
int dp[maxn][maxn];
int cnt[maxn];
int main()
{
    //dp[i][j]表示第i个人在第一个的时候,此时有j个非空队,队伍中的最大人数
    memset(dp,0,sizeof(dp));
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);
    for(int i=0;i<n;i++)
    {
        cnt[i]=upper_bound(a,a+n,a[i]+5)-a-i;//如果i号人站第一个,这个队最多有多少人
    }
    //for(int i=0;i<n;i++)cout<<cnt[i]<<' ';
    //cout<<endl;
    int ans=0;
    for(int i=0;i<n;i++)//第i号人
    {
        for(int j=0;j<=m;j++)//当前队数
        {
            dp[i+1][j]=max(dp[i][j],dp[i+1][j]);//是否跳过第i+1个人
            ans=max(ans,dp[i+1][j]);
            if(j+1<=m)
            {
                dp[i+cnt[i]][j+1]=max(dp[i+cnt[i]][j+1],dp[i][j]+cnt[i]);
                ans=max(dp[i+cnt[i]][j+1],ans);
            }
        }
    }cout<<ans<<endl;

    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值