首页 > 其他 > 详细

题解CF1133E K Balanced Teams

时间:2019-10-18 16:37:46      阅读:73      评论:0      收藏:0      [点我收藏+]

题目:CF1133E K Balanced Teams

拿到手第一想法就是算一下每个人可以和他分一起的,然后贪心。很显然在1s内被自己hack。所以贪心不行优先考虑dp。看到n和k的范围明显是个O(n^2)的dp。

由于我们不考虑顺序,按常规把水平排个序。

我的最初想法:

设f[i][j]:前i个人分了j组的最大和。

1.h[i]-h[lst]<=5 我们可以把他分到j-1组也可以分到第j组

2.h[i]-h[lst]>5 只能把i分到第j组

但我们遇到一个问题,就是我们不清楚第j-1组的开头到底是哪个。所以我又重新思考了一下:

f[i][j]=Max(f[i-1][j],f[lst][j-1]+i-lst);

表示第i个人是分到第j组还是和lst+1~i-1的数一起分到第j-1组。

此处的lst是最晚的不可以和i分到一组的,或者说最早可以和i分到一组的前一个。这样可以保证答案最大。

然后由于a[i]是升序的,这次的lst直接从上次的往后移就行。

 

技术分享图片
 1 #include<stdio.h>
 2 #include<algorithm>
 3 #define it register int
 4 #define il inline
 5 using namespace std;
 6 const int N=5005;
 7 int n,k,a[N],ans,f[N][N];
 8 il void fr(int &num){
 9     num=0;char c=getchar();int p=1;
10     while(c<0||c>9) c==-?p=-1,c=getchar():c=getchar();
11     while(c>=0&&c<=9) num=num*10+c-0,c=getchar();
12     num*=p;
13 }
14 il int Max(it p,it q){
15     return p>q?p:q;
16 }
17 int main(){ 
18     fr(n),fr(k);
19     for(it i=1;i<=n;++i) fr(a[i]);
20     sort(a+1,a+1+n); 
21     for(it i=1,lst=0;i<=n;++i){
22         while(a[i]-a[lst+1]>5) ++lst;
23         for(it j=1;j<=k;++j) f[i][j]=Max(f[i-1][j],f[lst][j-1]+i-lst);
24     }
25     for(it i=1;i<=k;++i) ans=Max(ans,f[n][i]);
26     printf("%d",ans);
27     return 0;
28 }
View Code

 

题解CF1133E K Balanced Teams

原文:https://www.cnblogs.com/Kylin-xy/p/11698461.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!