zoukankan      html  css  js  c++  java
  • [DP][二分]JZOJ 3463 军训

    Description

    HYSBZ 开学了!今年HYSBZ 有n 个男生来上学,学号为1…n,每个学生都必须参加军训。在这种比较堕落的学校里,每个男生都会有Gi 个女朋友,而且每个人都会有一个欠扁值Hi。学校为了保证军训时教官不会因为学生们都是人生赢家或者是太欠扁而发生打架事故,所以要把学生们分班,并做出了如下要求:

    1.分班必须按照学号顺序来,即不能在一个班上出现学号不连续的情况。

    2.每个学生必须要被分到某个班上。

    3.每个班的欠扁值定义为该班中欠扁值最高的那名同学的欠扁值。所有班的欠扁值之和不得超过Limit。

    4.每个班的女友指数定义为该班中所有同学的女友数量之和。在满足条件1、2、3 的情况下,分班应使得女友指数最高的那个班的女友指数最小。

    请你帮HYSBZ 的教务处完成分班工作,并输出女友指数最高的班级的女友指数。

    输入数据保证题目有解。
     

    Input

    第一行仅2 个正整数n, Limit,分别为学生数量和欠扁值之和的上限。

    接下来n 行每行2 个正整数Hi,Gi,分别为学号为i 的学生的欠扁值和女友数。

    Output

    仅1 个正整数,表示满足分班的条件下女友指数最高的班级的女友指数。
     

    Sample Input

    4 6
    4 3
    3 5
    2 2
    2 4

    Sample Output

    8
    【样例解释】
    分班按照(1,2),(3,4)进行,这时班级欠扁值之和为4+2=6<=Limit,而女友指数最高的班级为(1,2),为8。容易看出该分班方案可得到最佳答案。
     
     

    Data Constraint

    对于20%的数据:n,Limit<=100

    对于40%的数据:n<=1000

    对于100%的数据:1<=n,Gi<=20000,1<=Hi,Limit<=10^7

    分析

    由于求max-min问题,发现满足二分性以后,可以考虑二分

    然后我们想到DP判断

    fi为到i为止(不包括i)的最小欠扁值之和

    然后方程容易得到:

    f[i]=∑min(f[j]+max(h[j]..h[i]))

    但是枚举j显然不太现实,O(n^2)的时间复杂度

    然后注意到max(f[j]..f[i])是满足单调性的(单调下降或不变)

    那么我们设nexti为从i往后第一个满足hnext[i]>hi的位置

    那么显然若i≤j<nexti,则max(h[i]..h[j])不变

    那么我们可以直接跳过j,跳到nexti即可

    时间复杂度为O(knlogn)k为常数(不会算next的时间复杂度,因为数据是可以卡掉的,如果h满足单调上升就可以卡住next,使k退化为n,但是显然没有卡【滑稽】)

    #include <iostream>
    #include <cstdio>
    #include <memory.h>
    #define rep(i,a,b) for (i=a;i<=b;i++)
    const int N=20002;
    using namespace std;
    int next[N],nstk[N];
    long long sumofg[N],stk[N];
    int n;
    long long limit;
    int g[N],h[N];
    
    int Get_Right(int x,long long lmt) {
        int l=x,r=n,mid;
        while (l<r) {
            mid=l+r>>1;
            if (sumofg[mid]-sumofg[x-1]>=lmt) r=mid;
            else l=mid+1;
        }
        return l;
    }
    
    bool Judge(long long lmt) {
        int i;
        long long f[N];
        memset(f,0xf,sizeof f);
        f[1]=0;
        rep(i,1,n) {
            int j=Get_Right(i,lmt),k;
            long long mx;
            if (sumofg[j]-sumofg[i-1]>lmt) j--;
            k=i;mx=h[i];
            while (k<=j) {
                f[k]=min(f[k],f[i]+mx);
                mx=h[k];
                k=next[k];
            }
            f[j+1]=min(f[j+1],f[i]+mx);
        }
        return f[n+1]<=limit;
    }
    
    int main() {
        int i,top=1;
        scanf("%d%lld",&n,&limit);
        rep(i,1,n) {
            scanf("%d%d",&h[i],&g[i]);
            sumofg[i]=sumofg[i-1]+g[i];
        }
        stk[top]=2147483647;
        nstk[top]=n+1;
        for (i=n;i;i--) {
            while (h[i]>=stk[top]) top--;
            next[i]=nstk[top];
            top++;
            stk[top]=h[i];
            nstk[top]=i;
        }
        long long l=1,r=sumofg[n],mid,ans=sumofg[n];
        while (l<r) {
            mid=l+r>>1;
            if (Judge(mid)) {
                ans=min(ans,mid);
                r=mid;
            }
            else l=mid+1;
        }
        printf("%lld",ans);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    Liberty Mutual Property Inspection, Winner's Interview: Qingchen Wang
    均方根值(RMS)+ 均方根误差(RMSE)+标准差(Standard Deviation)
    Comparing Differently Trained Models
    Stochastic Optimization Techniques
    Here’s just a fraction of what you can do with linear algebra
    14种机器学习常见算法分类汇总
    高速充电技术介绍
    javacc学习总结
    组合查询(机房重构知识点总结)
    Linux下vi编辑器的使用
  • 原文地址:https://www.cnblogs.com/mastervan/p/9387510.html
Copyright © 2011-2022 走看看