Educational Codeforces Round 44 - E. Pencils and Boxes

标签 : DP


题目链接

http://codeforces.com/contest/985/problem/E

题意

把\(n\)个数分成多组,使得每组包含至少\(k\)个元素,且每组中的任意两个元素之差不超过\(d\)

分析

  • 很巧妙的DP
  • 我们使用dp[i]来表示(如果不存在i+1~n个元素的时候)前i个能否满足题目条件放入boxes中。
  • dp[i]true当且仅当存在一个j满足
  • \[
    \left\{
    \begin{aligned}
    a[j+1] \geq a[i]-d \\
    dp[j]=true\i-j \geq k \\end{aligned}
    \right.
    \]

    也就是说我们存在一个j使得可以把前j个在满足题目条件的情况下放入盒子。然后j+1~i个元素可以放到一个盒子里。

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=500050;
int sum[maxn],n,k,d,a[maxn];
bool f[maxn];
queue<int> q,s;
int main(){
    scanf("%d%d%d", &n,&k,&d);
    for(int i = 1; i <= n; ++i) scanf("%d",a+i);
    sort(a+1,a+1+n);
    q.push(1);
    for(int i = 1; i <= n; ++i){
        while(!s.empty()&&a[s.front()]<a[i]-d) s.pop();
        s.push(i);
        int p = s.front();
        while(!q.empty()&&q.front()<p) q.pop();
        if(!q.empty()&&i-q.front()+1>=k) f[i]=true,q.push(i+1);
    }
    cout << (f[n]?"YES":"NO") << endl;
    return 0;
}

原文地址:https://www.cnblogs.com/sciorz/p/9092616.html

时间: 2024-10-12 02:23:17

Educational Codeforces Round 44 - E. Pencils and Boxes的相关文章

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://codeforces.com/contest/985/problem/E Description Mishka received a gift of multicolored pencils for his birthday! Unfortunately he lives in a monochrome w

Educational Codeforces Round 44 (Rated for Div. 2)+E. Pencils and Boxes+树状数组

题目链接:E. Pencils and Boxes 题意:N 个数,要求分成任意堆,要求每一堆只要有K个,同一堆中任意数之间差值不能超过d; 题解:用树状数组.排一下序然后从后面开始找,以当前数为最小值看能否成堆,要成堆的话要求i+k,到第一个大于a[i]+d的位置之间有能够成堆的位置.(这里判断的时候树状数组一减看是否大于0就可以了)注意初始化时在n+1的位置加1. 1 #include<bits/stdc++.h> 2 #include <iostream> 3 #includ

Educational Codeforces Round 44#985DSand Fortress+二分

传送门:送你去985D: 题意: 你有n袋沙包,在第一个沙包高度不超过H的条件下,满足相邻两个沙包高度差小于等于1的条件下(注意最小一定可以为0),求最少的沙包堆数: 思路: 画成图来说,有两种可能,一种是y=h-x一次函数和常函数y=x组合,还有一种是先上升后下降的函数,注意斜率绝对值都是1: 二分答案,具体来说,我是二分了最大高度,主要是check()比较要思考,(昨天晚上没有细心写check,错过了很多AC:): 这个check中:如果最大高度 mid 比m小,说明不会有折线,直接考虑三角

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

Educational Codeforces Round 23 F. MEX Queries(线段树)

题目链接:Educational Codeforces Round 23 F. MEX Queries 题意: 一共有n个操作. 1.  将[l,r]区间的数标记为1. 2.  将[l,r]区间的数标记为0. 3.  将[l,r]区间取反. 对每个操作,输出标记为0的最小正整数. 题解: hash后,用线段树xjb标记一下就行了. 1 #include<bits/stdc++.h> 2 #define ls l,m,rt<<1 3 #define rs m+1,r,rt<&l

Educational Codeforces Round 22 E. Army Creation(主席树)

题目链接:Educational Codeforces Round 22 E. Army Creation 题意: 给你n个数和一个数k,然后有q个询问. 每个询问 有一个区间[l,r],问你这个区间内在满足每一种数不超过k的情况下,最大能选多少个数出来. 强制在线. 题解: 一看就要用到主席树,和主席数求区间内有多少不同的数的个数处理方法相同. 依次将每个数插入,当这个数出现的个数等于k了,就把最前面的那个数删掉. 然后询问就访问root[r]就行了. 第一次写完数据结构没有调试一遍过样例,一

Educational Codeforces Round 21 F. Card Game(网络流之最大点权独立集)

题目链接:Educational Codeforces Round 21 F. Card Game 题意: 有n个卡片,每个卡片有三个值:p,c,l; 现在让你找一个最小的L,使得满足选出来的卡片l<=L,并且所有卡片的p的和不小于k. 选择卡片时有限制,任意两张卡片的c之和不能为质数. 题解: 和hdu 1565 方格取数(2)一样,都是求最大点权独立集. 不难看出来,这题再多一个二分. 注意的是在构造二部图的时候,按照c值的奇偶性构造. 当c==1时要单独处理,因为如果有多个c==1的卡片,

Educational Codeforces Round 36 (Rated for Div. 2)

Educational Codeforces Round 36 (Rated for Div. 2) F. Imbalance Value of a Tree You are given a tree T consisting of n vertices. A number is written on each vertex; the number written on vertex i is ai. Let's denote the function I(x,?y) as the differ

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars There are n pillars aligned in a row and numbered from 1 to n. Initially each pillar contains exactly one disk. The i-th pillar contains a disk having radius ai. You can move these disks