[Codevs3342] green channel

Description

"Siyuan entrance green channel" (Green Passage, GP) is one commonly used in Tangshan, a workbook, a large amount of questions of their hated by many oiers of lsz etc., among which the most math green channel. On a certain day, soon-if (on behalf of math), and again announced to close this operation, but also a little lsz did not write ......

High School Mathematics "green channel" a total of n channel topic to write (in fact copied), number 1..n, copy each question the time spent is not the same, copy the first question i spend a [i] minutes. Since lsz but also to prepare NOIP, obviously can not write all day long green channel. lsz decided to use only no more than t minutes to copy this, it will inevitably be free of the problem. Each question either did not write or copy complete, can not write half. A contiguous empty empty title is called a title segment, its length is included in the title number. This will cause the horse to respond to natural teacher anger. Degree (referred to as angry degrees) Ma angry is equal to the longest length of empty title.

Now, lsz want to know what questions he wrote in this t minutes, to be able to minimize the anger of the horse teacher. Since lsz very smart, you simply tell him the value of anger on it, without output program. (Happy melt: So lsz how not to write their own procedures lsz:? I also copied other subjects work ......)

Input

The first two acts of integers n, t, representative of a total of n channel title, t minutes.

Following line, the n is an integer, followed by a [1], a [2], ... a [n], as described above meaning.

Output

Only one line, an integer w, the lowest degree of anger.

Sample Input

17 11
6 4 5 2 5 3 4 5 2 3 4 5 2 3 6 3 5

Sample Output

3

Hint

60% of the data n <= 2000

100%数据 0<n<=50000,0<a[i]<=3000,0<t<=100000000

answer

Extreme Value Problems, half the answer law? \ (DP \) ?

Since we know \ (W ~ \ Epsilon \ left [0, n-\ right] \) ,So we can enumerate the value of wSince \ (0 <n≤50000 \) and \ (W \) the greater the smaller the time, so we can answer two points, to determine plus

How can I tell? \ (DP \) ?

First to a simple, we request is empty title in the largest segment \ (mid \) when, in \ (n \) title selective shortest time required to do,

Then we can use \ (a [i] \) expressed as the section \ (I \) title time used by \ (f [i] \) represents meet the maximum empty title segment \ (MID \) when the front \ (i-1 \) title done selectively, the first \ (I \) title shall be the minimum time used,

Then the state transition equation of \ (f [i] = min \ left \ {f [k]] \ right \} \ left (k ~ \ epsilon \ left [i-1-mid, i-1 \ right] \ right ) + A [I] \) .

At this point we need to re-cycle the first enumeration is currently considered the first few questions, the second heavy cycle enumeration \ (K \) , then \ (the DP \) time complexity is \ (O (n ^ {mid }) \) , plus two time points, a total of \ (O (LOG_ {n-2} \ {^ n-times MID}) \) , should be timed out.

Rethinking, we want to transfer \ (f [k] \) is certainly the smallest within each range, this is not a queue can be monotonous it? With \ (Q [] \) to maintain monotonicity, the following steps:

  • Maintains a monotonically increasing monotone queue, question number satisfying the condition of the recording, which may be the optimal solution of the question number;

  • When the first team monotonous queue exceeds the range currently considered, it kicked out of the queue;

  • Maintaining monotonicity of the queue and the queue this solution was added

details as follows:

for(int i=1;i<=n;++i)
{
    while(q[l]+mid<i) ++l;
    f[i]=f[q[l]]+a[i];
    while(f[i]<=f[q[r]]) --r;
    ++r,q[r]=i;
}
  • Pit : because the first \ (n \) questions do not have to choose, so we \ (n \) questions make selective shortest time required for the \ ([n + 1] f \)

\(My~Code:\)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int N=50005;
int n,t,a[N],f[N],q[N];

bool DP(int mid)//单调队列优化DP
{
    int l,r;
    f[0]=0,q[1]=0,l=r=1;
    ++mid;//方便计算
    for(int i=1;i<=n;++i)
    {
        while(q[l]+mid<i) ++l;
        f[i]=f[q[l]]+a[i];
        while(f[i]<=f[q[r]]) --r;
        ++r,q[r]=i;
    }
    if(f[n]<=t) return 1;
    return 0;
}

void Brinary()//二分答案法
{
    int l=0,r=n,mid,Ans;
    ++n;//坑点处理
    for(;l<=r;)
    {
        mid=(l+r)>>1;
        if(DP(mid)) Ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",Ans);
}

int main()
{
    scanf("%d%d",&n,&t);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    Brinary();
    return 0;
}

Guess you like

Origin www.cnblogs.com/hihocoder/p/12195479.html