CF #544 div3 E. K Balanced Teams

题意:有n个学生 要求组成k个小组 每个小组中两两差值不得超过5 可以有学生不被编入组中 求最多可以有多少个学生被编入组中

n,k<=1e5

题解:

考虑dp[i][j],i为前i个学生,j为分了几组的最大人数,不选第i个人,dp[i][j]=dp[i-1][j],

选第i个人,贪心的选择距离a[i]小于等于5的最远那个点-1,记作pos[i],dp[i][j]=dp[pos[i]][j-1]+i-pos

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

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define check system("pause")
#define all(x) (x).begin(),(x).end()
#define de(a) cout<<#a<<" = "<<a<<endl
#define dd(a) cout<<#a<<" = "<<a<<" "
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define lowbit(a) ((a)&-(a))
#define INF 0x3f3f3f3f
const ll mod = 1e9+7;
const int N = 5e3+20;
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define mes(p,b) memset(p,b,sizeof(p))
#define sz(x) int(x.size())
int n,k,dp[N][N],a[N],pos[N];
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);
  rep(i,1,n){
      dep(j,i,1){
          if(a[i]-a[j]<=5) pos[i]=j-1;
          else break;
      }
  }
  int ans=0;
  dp[1][1]=1;
  rep(i,1,n)
      rep(j,1,k)
        dp[i][j]=max(dp[i-1][j],dp[pos[i]][j-1]+i-pos[i]);
  rep(j,1,k) ans=max(ans,dp[n][j]);
  cout<<ans;
  return 0;
}

原文地址:https://www.cnblogs.com/FZUlh/p/12388808.html

时间: 2024-10-17 13:46:16

CF #544 div3 E. K Balanced Teams的相关文章

【CF1133E】K Balanced Teams(动态规划,单调队列)

[CF1133E]K Balanced Teams(动态规划,单调队列) 题面 CF 让你把一堆数选一些出来分成不超过\(K\)组,每一组里面的最大值和最小值之差不超过\(5\),求最多有多少个人元素可以被分组. 题解 设\(f[i][j]\)表示把前\(i\)个数分成\(j\)组的最多人数. 然后单调队列转移一下完了. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring&g

题解CF1133E K Balanced Teams

题目: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组的开头

codeforces 1133E K Balanced Teams

题目链接:http://codeforces.com/contest/1133/problem/E 题目大意: 在n个人中找到k个队伍.每个队伍必须满足最大值减最小值不超过5.求满足条件k个队伍人数的总和的最大值. 这个题写DP很多的人应该可以很快写出来吧,毕竟不是很难. 思路: 反正最多n^2种状态.用数组存就好了. 先排序. 对于每个点,dp[a][b].表示a到n区间里分b个队伍的答案. 如果a是答案dp[a][b]所需要的,那么我们从a开始到a+i暴力一下(此时,x[a+i]-x[a]>

Balanced Teams (USACO Jan Bronze 2014)

既然是bronze,毫无压力的AC了. 就是个深搜,当然加个剪枝--最后一个组不用搜. 恩可以一个一个组分层次dfs,这样会跑得飞起~~也不容易错 #include <cstdio> int f[13],i,su,tt1,tt2,lev[4],min; bool has[13]; inline int md(int a,int b,int c,int d){ tt1=a,tt2=a; if(tt1<b)tt1=b; if(tt1<c)tt1=c; if(tt1<d)tt1=d

Codeforces Round #544 (Div. 3) C. Balanced Team [暴力剪枝]

You are a coach at your local university. There are n n students under your supervision, the programming skill of the i i -th student is a i ai . You have to create a team for a new programming competition. As you know, the more students some team ha

CF 999 div3

A 从左往右扫一遍统计答案,如果等于n就输出n,否则再从右往左扫一遍,再原来的答案上累加答案 #include <iostream> #include <cstdio> using namespace std; int a[105], n, k; int main() { cin >> n >> k; for (int i = 1; i <= n; ++i) cin >> a[i]; int ans = 0; for (int i = 1;

CF #624 div3

# A 题意: 给定a,b,通过对a的操作使得a,b相等,只能加奇数,减偶数,至少需要多少次操作 题解: 操作最多是2只需要判断奇偶即可,最多通过一次操作改变奇偶,再补上差值 1 #include<bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 int t; 5 cin>>t; 6 while(t--){ 7 int a,b; 8 cin>>a>>b; 9 int ans=1; 10 if(a==b

hiho一下 第115周:网络流一?Ford-Fulkerson算法 (Edmond-Karp,Dinic,SAP)

来看一道最大流模板水题,借这道题来学习一下最大流的几个算法. 分别用Edmond-Karp,Dinic ,SAP来实现最大流算法. 从运行结过来看明显SAP+当前弧优化+gap优化速度最快.   hiho一下 第115周:网络流一•Ford-Fulkerson算法 原题网址:http://hihocoder.com/contest/hiho115/problem/1 网络流一·Ford-Fulkerson算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和

数据挖掘十大算法之Appriori算法

1.引言      Appriori算法是用来干什么的?主要是用来解决类似于这样的问题:如果客户买了啤酒,他还会去买尿布吗? 理论的核心: 频繁项目集的子集仍是频繁项目集:非频繁项目集的超集是非频繁项目集.这个理论一直作为经典的数据挖掘理论被应用. 定理(Appriori 属性1). 如果项目集X是频繁项目集,那么它的所有非空子集都是频繁项目集. 定理(Appriori 属性2). 如果项目集X是非频繁项目集,那么它的所有超集都是非频繁项目集. 2.以一个实例来说明Appriori算法 题目:数