题意:有\(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;
}
Codeforces Round #544 (Div. 3) E. K Balanced Teams (DP)
原文:https://www.cnblogs.com/lr599909928/p/13951832.html