返回顶部

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

  • 题意:有\(n\)个人,每个人的能力值是\(a_i\),现在你想将这些人分成\(k\)组(没必要全选),但是每组中最高水平和最低水平的人的能力差值必须\(\le 5\),问最多能选多少人.

  • 题解:想了一会发现纯贪心写不了,必须要用dp来求解,先排序,我们记\(dp[i,j]\),表示前\(i\)个人分成\(j\)组选的最多的人数,当便遍历到某个人的时候,他可以不加任何组\(dp[i][j]=dp[i-1][j]\),否则如果他要加入,那么我们往前找到第一个与其能力差值\(>5\)的位置\(pos\),然后在\([1,pos]\)这些人已经分成\(j-1\)组的情况下将\([pos+1,i]\)这些人分成一组一定是最优的,于是\(dp[i][j]=max(dp[i][j],dp[pos][j-1]+i-pos)\).

  • 代码:

    int n,k;
    int a[N];
    int dp[5010][5010];
     
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        cin>>n>>k;
        rep(i,1,n) cin>>a[i];
     
        sort(a+1,a+1+n);
     
        dp[1][1]=1;
        rep(i,1,n){
        	int las=i;
        	while(a[i]-a[las]<=5 && las>=1) las--;
        	rep(j,1,min(i,k)){
        		dp[i][j]=dp[i-1][j];
        		dp[i][j]=max(dp[i][j],dp[las][j-1]+i-las);
        	}
        }
     
        int ans=0;
        rep(j,1,k) ans=max(ans,dp[n][j]);
     
     
        cout<<ans<<'\n';
     
        return 0;
    }
    
posted @ 2020-11-10 00:27  Rayotaku  阅读(86)  评论(0编辑  收藏  举报