https://codeforces.com/contest/1133/problem/E

Codeforces Round #544 (Div. 3) E. K Balanced Teams // dp

 Codeforces Round #544 (Div. 3) E. K Balanced Teams // dp

求分成k组,使得每一组max-min小于5的最多的可选人数。

先排序(下面都是基于排好序的操作)

定义dp[i][j] (排好序第i个人前,已有j组的最大人数)

dp[i][j]=max(dp[i-1][j],dp[p[i]-1][j-1]+i-p[i]+1);

其中 p[i] 表示第i个人作为最后一人可以延展到的最前面的位置即可以组队的人的最小的i。

/**< 2019年3月18日 20:47:58 */
#include <bits/stdc++.h>
using namespace std;
int dp[5005][5005];
int p[5005];int a[5005];
int main(){
    ios::sync_with_stdio(false);
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+n);
    a[0]=INT_MIN/2;
    for(int i=1;i<=n;i++){
        for(int j=i-1;;j--){
            if(a[i]-a[j]>5) {
                p[i]=j+1;
                break;
            }
        }
    }
    int ans=INT_MIN;
    memset(dp,-1,sizeof(dp));
    for(int i=1;i<=n;i++){
        dp[i][1]=max(i-p[i]+1,dp[i-1][1]);
        ans=max(ans,dp[i][1]);
    }
    for(int j=2;j<=k;j++){
        for(int i=1;i<=n;i++){
            dp[i][j]=max(dp[i-1][j],dp[p[i]-1][j-1]+i-p[i]+1);
            ans=max(ans,dp[i][j]);
        }
    }
    cout<<ans;
    return 0;
}

 

相关文章: