zoukankan      html  css  js  c++  java
  • lightoj 1084

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1084

    题解:不妨设dp[i] 表示考虑到第i个点时最少有几组那么

    if a[i]-a[i-j]<=2*k (j>=2)

    then dp[i]=min(dp[i],dp[i-j]+1)。所以先要排序,然后用二分找到最小的j然后用线段树或者其他的方法查询(i-1~i-j)的最小值。

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #define inf 0X3f3f3f3f
    using namespace std;
    const int M = 1e5 + 10;
    struct TnT {
        int l , r , Min;
    }T[M << 2];
    void push_up(int i) {
        T[i].Min = min(T[i << 1].Min , T[(i << 1) | 1].Min);
    }
    void build(int l , int r , int i) {
        int mid = (l + r) >> 1;
        T[i].l = l , T[i].r = r , T[i].Min = inf;
        if(l == r) return ;
        build(l , mid , i << 1);
        build(mid + 1 , r , (i << 1) | 1);
        push_up(i);
    }
    void update(int pos , int i , int num) {
        int mid = (T[i].l + T[i].r) >> 1;
        if(T[i].l == pos && T[i].r == pos) {
            T[i].Min = num;
            return ;
        }
        if(mid < pos) update(pos , (i << 1) | 1 , num);
        else update(pos , i << 1 , num);
        push_up(i);
    }
    int query(int l , int r , int i) {
        int mid = (T[i].l + T[i].r) >> 1;
        if(T[i].l == l && T[i].r == r) {
            return T[i].Min;
        }
        if(mid < l) return query(l , r , (i << 1) | 1);
        else if(mid >= r) return query(l , r , i << 1);
        else return min(query(l , mid , i << 1) , query(mid + 1 , r , (i << 1) | 1));
    }
    int dp[M] , a[M] , n , k;
    int binsearch(int l , int r , int num) {
        int mid = (l + r) >> 1;
        int ans = inf;
        while(l <= r) {
            mid = (l + r) >> 1;
            if(num - a[mid] <= 2 * k) {
                ans = mid;
                r = mid - 1;
            }
            else l = mid + 1;
        }
        return ans;
    }
    int main() {
        int t , Case = 0;
        scanf("%d" , &t);
        while(t--) {
            scanf("%d%d" , &n , &k);
            for(int i = 1 ; i <= n ; i++) scanf("%d" , &a[i]);
            sort(a + 1 , a + 1 + n);
            memset(dp , inf , sizeof(dp));
            dp[0] = 0;
            printf("Case %d: " , ++Case);
            if(n < 3) {
                printf("-1
    ");
                continue;
            }
            build(0 , n , 1);
            update(0 , 1 , 0);
            for(int i = 3 ; i <= n ; i++) {
                if(a[i] - a[i - 2] <= 2 * k) {
                    int pos = i - 3;
                    int gg = binsearch(1 , i - 3 , a[i]);
                    pos = min(gg - 1 , pos);
                    int gl = query(pos , i - 3 , 1);
                    dp[i] = min(gl + 1 , dp[i]);
                    update(i , 1 , dp[i]);
                }
            }
            if(dp[n] == inf) printf("-1
    ");
            else printf("%d
    " , dp[n]);
        }
        return 0;
    }
    
  • 相关阅读:
    CPP STL学习笔记
    CPP 设计模式学习
    blackarch 安装指南
    通过 Http 请求获取 GitHub 文件内容
    实践
    升级
    部署-MySql 之Linux篇
    数据库
    RxJs
    Vue
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7153703.html
Copyright © 2011-2022 走看看