zoukankan      html  css  js  c++  java
  • E. Pencils and Boxes 题解(双指针+dp)

    题目链接

    题目大意

    你有 n 只铅笔,每个铅笔的饱和度是 a[i]。

    现在你要把铅笔放进盒子里,盒子可以有任意个,但是每个盒子里至少要放 k 只铅笔。

    并且对于一个盒子里任意两只铅笔 i 和 j 必须满足他们的饱和度差异不超过 d

    即 |a[i] - a[j]| ≤ d问是否存在一种可行的放法。

    1 ≤ k ≤ n ≤ 500000, d, a[i] ≤ 10^9

    题目思路

    其实仔细思考是一个很简单的dp

    显然我们发现把 a 数列排序后按顺序划分一定是最优的。

    因此我们可以先对 a 数列从小到大排序,然后用 (dp[i])表示能否把前 i 个放进盒子里

    然后再用双指针和前缀和优化下dp即可

    代码

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define fi first
    #define se second
    #define debug cout<<"I AM HERE"<<endl;
    using namespace std;
    typedef long long ll;
    const int maxn=5e5+5,inf=0x3f3f3f3f,mod=1234567891;
    const double eps=1e-6;
    int n,k,d;
    int a[maxn];
    int dp[maxn],pre[maxn];
    bool ask(int l,int r){
        if(r<l){
            return 0;
        }else if(l<=0){
            return pre[r]>0;
        }else{
            return pre[r]-pre[l-1]>0;
        }
    }
    signed 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);
        int l=0;
        dp[0]=1;
        pre[0]=1;
        for(int i=1;i<=n;i++){
            while(a[i]-a[l]>d) l++;
            dp[i]=ask(l-1,i-k);
            pre[i]=pre[i-1]+dp[i];
        }
        printf(dp[n]?"YES
    ":"NO
    ");
        return 0;
    }
    
    
    不摆烂了,写题
  • 相关阅读:
    OCP-052考试题库汇总(35)-CUUG内部解答版
    OCP-052考试题库汇总(34)-CUUG内部解答版
    018 ThreadLocal实现线程安全
    017 无锁与CAS
    016 原子类
    015 可见性问题与volatile
    014 锁重入
    013 synchronized的优化
    012 内置锁和synchronized
    011 线程安全性问题
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/15182445.html
Copyright © 2011-2022 走看看