zoukankan      html  css  js  c++  java
  • Codeforces 985E

    题意略。

    思路:

    这个题目开始想的有点暴力,后来发现有搜索的性质,因此转而用动态规划。首先,我们要把这些数排个序。

    定义状态:dp[i]为排序后i~n能否成功打包,1表示可以,0表示不能打包。

    状态转移方程:dp[i] = max{dp[j]} (i + k <= j <= upper)upper为在有序数组中,第一个比当前值store[i] + d大的数的下标。

    为了防止它卡数据,这里可以用单调队列优化一下,由于确定upper要使用二分搜索,所以总的复杂度是O(nlogn)。

    详见代码:

    #include<bits/stdc++.h>
    #define maxn 500005
    using namespace std;
    
    int dp[maxn],que[maxn],head,tail,store[maxn];
    int n,k,d;
    
    int main(){
        scanf("%d%d%d",&n,&k,&d);
        for(int i = 1;i <= n;++i) scanf("%d",&store[i]);
        sort(store + 1,store + 1 + n);
        dp[n + 1] = 1;
        for(int i = n;i >= 1;--i){
            int temp = store[i] + d;
            int r = upper_bound(store + 1,store + 1 + n,temp) - store;
            int l = i + k;
            if(l > r){
                dp[i] = 0;
            } 
            else{
                while(que[head] > r && head < tail) ++head;
                while(head < tail && dp[que[tail - 1]] < dp[l]) --tail;
                que[tail++] = l;
                dp[i] = dp[que[head]];
            }
        }
        printf("%s
    ",dp[1] ? "YES" : "NO");
        return 0;
    }
    
    /*
    18 3 1
    1 1 1 2 2 3 5 5 5 6 6 7 9 9 9 10 10 11
    
    YES
    */
  • 相关阅读:
    [saiku] 系统登录成功后查询Cubes
    216. Combination Sum III
    215. Kth Largest Element in an Array
    214. Shortest Palindrome
    213. House Robber II
    212. Word Search II
    211. Add and Search Word
    210. Course Schedule II
    分硬币问题
    开始学习Python
  • 原文地址:https://www.cnblogs.com/tiberius/p/9162380.html
Copyright © 2011-2022 走看看