You are a coach at your local university. There are n students under your supervision, the programming skill of the i-th student is ai.
You have to form k teams for yet another new programming competition. As you know, the more students are involved in competition the more probable the victory of your university is! So you have to form no more than k (and at least one) non-empty teams so that the total number of students in them is maximized. But you also know that each team should be balanced. It means that the programming skill of each pair of students in each team should differ by no more than 5. Teams are independent from one another (it means that the difference between programming skills of two students from two different teams does not matter).
It is possible that some students not be included in any team at all.
Your task is to report the maximum possible total number of students in no more than k(and at least one) non-empty balanced teams.
If you are Python programmer, consider using PyPy instead of Python when you submit your code.
Input
The first line of the input contains two integers n
and k (1≤k≤n≤5000) — the number of students and the maximum number of teams, correspondingly.
The second line of the input contains n
integers a1,a2,…,an (1≤ai≤109), where ai is a programming skill of the i-th student.
Output
Print one integer — the maximum possible total number of students in no more than k(and at least one) non-empty balanced teams.
Examples
Input
5 2
1 2 15 15 15
Output
5
Input
6 1
36 4 1 25 9 16
Output
2
Input
4 4
1 10 100 1000
Output
4
一共有n个人,每个人有一个能力值,要分成不超过k队,每队不限人数,但要求队伍中任意两人的能力值相差不超过5,求最多能有多少人能分到队伍中。
首先,先求出如果第i人为队伍中得最大值时,这个队伍可以有哪些人。排序加双指针,遍历一遍就完事。
预处理之后,进行动态规划的设计。记数组dp[i][j],为前i个人(不包括i),分成j组时,最多有多少人能分到队伍中。之后根据所设计的数组,考虑在第i个人,分成j组时的情况。我们可以选择
- 将第i个人为新队伍的最大值新建一只队伍
假设从第i个人到第k个人可以分到一组,而第k+1个人不能与第i个人一组。因为区间[i,k]之间的已经被拉到一个队伍中,所以若第i个人新开一组,那么应该跳到 第k+1个人分为j+1组时的情况 - 第i个人不分组
跳转到下一个人,即第i+1个人分为j组的情况
综上,有状态转移方程
dp[i+1][j]=max(dp[i][j],dp[i+1][j]);
dp[i+N[i]][j+1]=max(dp[i+N[i]][j+1],dp[i][j]+N[i]);
#include <stdio.h>
#include <climits>
#include <cstring>
#include <time.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <vector>
#include <string>
#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;
int store[5005];
int N[5005],jump[5005];
int dp[5002][5005];
inline bool cmp(const int &a,const int &b);
int main(){
ios::sync_with_stdio(false);
int n,k;
cin>>n>>k;
rep(i,1,n+1){
cin>>store[i];
}
//Ascending
sort(store+1,store+n+1,cmp);
//get map
mem(N,0);
int pos=1,point=2;
while(pos<=n){
while(point<=n && store[pos]-store[point]<=5)
point++;
N[pos]+=point-pos;
pos++;
}
//Dynamic programming
mem(dp,0);
rep(i,1,n+1){
rep(j,0,min(i+1,k+1)){
dp[i+1][j]=max(dp[i][j],dp[i+1][j]);
dp[i+N[i]][j+1]=max(dp[i+N[i]][j+1],dp[i][j]+N[i]);
}
}
int ans=INT_MIN;
rep(i,0,k+1)
ans=max(ans,dp[n+1][i]);
cout<<ans<<endl;
re 0;
}
inline bool cmp(const int &a,const int &b){
re a>b;
}