zoukankan      html  css  js  c++  java
  • [acmm week12]二分+dp+单调队列

    1004 抄作业
         
     
    Time Limit: 1sec    Memory Limit:256MB
    Description

    Zfree虽然平时很爱学习,但是他迫于生活所迫(比如设计cpu实验啊),这周数分作业只能抄答案了。

    可是这是他第一次抄作业题目又多,于是他有些不想抄,因为他想玩会游戏再抄,于是他打算用一定的时间去抄作业(当然也可以不用完)。

    而这可能抄不完,所以他会选择跳过几题不抄,为了尽量不被老师发现,他想知道他抄写的两题的题号最大间隔最小是多少?(间隔包括他第一个抄的题目前面的题目数量 和 最后一个题目后面的题目数量)

    Input

    第一行 T,n 表示可以用来抄题目的总时间和题目数量(T,n<10^5)

    第二行 n个数字,第i个数字表示抄写第i题要用的时间数(a[i]<T)

    Output

     一个数字k,表示最多隔k题抄一题可以用T时间抄完题目

    Sample Input 
     
    10 5
    5 3 6 1 3
     
    Sample Output
     
    1

    题意:n个数,选取若干个数,其中两个数之间的间隔最大为k,问k最小是多少。

    题解:

    要最大值最小,二分k,然后dp判断当前的k是否可行。
    设dp[i]表示最大间隔不超过k的前提下,前i道题目中,选了第i道题,所用的最短时间。
    dp[i]=min(dp[j])+time[i], i-k-1<=j < i
    这个方程最坏情况是n^2的,但这种形式的方程我们可以用一个单调队列来优化。对于当前的i,队列q储存的可能的j值,满足其dp值递增,每次先判断对首的元素是否>=i-k-1,不满足则出队;用队首元素更新dp[i];若队尾的元素的dp值大于dp[i]则出队(这些元素此后都一定没有i优,不可能用于更新其他dp值),再把i放到队尾。这样总的复杂度就是O(nlogn)的。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int N=100010;
     5 int a[N],f[N],g[N];
     6 int t,n;
     7 
     8 void init()
     9 {
    10     scanf("%d%d",&t,&n);
    11     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    12     a[n+1]=0;
    13 }
    14 
    15 bool check(int k)
    16 {
    17     //f[i]=min(f[j])+a[i];  (i-k-1 <= j <= i-1)
    18     int l=1,r=1;
    19     f[0]=0;g[1]=0;
    20     for(int i=1;i<=n+1;i++)
    21     {
    22         while(l<=r && g[l]<i-k-1) l++;
    23         f[i]=f[g[l]]+a[i];
    24         while(l<=r && f[g[r]]>f[i]) r--;
    25         g[++r]=i;
    26     }
    27     return f[n+1]<=t;
    28 }
    29 
    30 void solve()
    31 {
    32     int l=0,r=n,mid;
    33     while(l<r)
    34     {
    35         mid=(l+r)/2;
    36         if(check(mid)) r=mid;
    37         else l=mid+1;
    38     }
    39     printf("%d
    ",l);
    40 }
    41 
    42 int main()
    43 {
    44     //freopen("a.in","r",stdin);
    45     init();
    46     solve();
    47     return 0;
    48 }
  • 相关阅读:
    关于求 p_i != i and p_i != i+1 的方案数的思考过程
    poj 3041 Asteroids 二分图最小覆盖点
    poj 1325 Machine Schedule 最小顶点覆盖
    poj 1011 Sticks 减枝搜索
    poj 1469 COURSES 最大匹配
    zoj 1516 Uncle Tom's Inherited Land 最大独立边集合(最大匹配)
    Path Cover (路径覆盖)
    hdu 3530 SubSequence TwoPoint单调队列维护最值
    zoj 1654 Place the Rebots 最大独立集转换成二分图最大独立边(最大匹配)
    poj 1466 Girls and Boys 二分图最大独立子集
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/10028659.html
Copyright © 2011-2022 走看看