Copying Books

Copying Books

Given a sequence of length m, \ (\ {a_i \} \) , which is divided into k intervals corresponding to the minimum interval of the program and the maximum requirements, a variety of programs, from left to right the press interval length as small as possible (i.e. from left to right interval length sequence of the lexicographically smallest configuration), \ (m, K \ Leq 500 \) .

solution

Obviously minimum think of the maximum-half, in fact dp can, because there can be recurrence interval division problem, but also it can find the answer.

Something equivalent to a half for time complexity is increased a \ (log (n) \) adds a known condition, although the premise is monotonous, but might in the future lack of conditions, consider dichotomy find monotonic.

We dichotomy \ (x \) representing the interval and the maximum value is not more than \ (x \) , then consider greedy (said to be in, and half of the back of the check is either greedy or is dp) half later, then from left to right scanning, dealing with a range, keep its right to increase numbers, when you want more than just, put the digital divide to the next section, we obviously got a number, meaning under current conditions is met the least number of intervals.

In fact, can be seen as a function \ (F (x) \) , apparently with an increase of x, would reduce the minimum number of sections, and x is exactly corresponding to a range of \ ([F (x), n-] \) , i.e. number range interval.

So when k time outside of this range, apparently \ (f (x) \) need to be reduced, that is, x increases, and vice versa (should write that \ (lower \ _bound \) half), so we get a minimum of x, just to frame k, apparently when whichever is greater than the value of x, the same condition is satisfied, but the result is not good, do not take a small fraction x satisfies the condition, then x is the answer of "premise."

So greedy according to previous methods, you can get a program, the minimum lexicographical, as long as you can from right to left greedy, but it is a minimal program of interval number, so just have to cut down some of the intervals, apparently can easily cut, and to ensure that the lexicographically smallest, then from left to right scan can be cut to cut, the final time complexity O (mlog (m)).

Reference Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
#define Size 550
using namespace std;
bool b[Size];
int a[Size],m;
il void read(int&);
il int fen(int);
int main(){
    //freopen("in","r",stdin);
    int lsy;read(lsy);
    while(lsy--){
        memset(b,0,sizeof(b));
        int k,l(0),r(0);read(m),read(k);
        for(int i(1);i<=m;++i)
            read(a[i]),r+=a[i],l=max(l,a[i]);
        int mid;while(l<=r){
            mid=l+r>>1;
            if(fen(mid)>k)l=mid+1;
            else r=mid-1;
        }int tot(1);
        for(int i(m),j(0);i;--i)
            if(j+a[i]<=l)j+=a[i];
            else j=a[i],b[i]=1,++tot;
        tot=k-tot;
        for(int i(1);i<=m;++i)
          if(tot&&!b[i])b[i]=1,--tot;
        for(int i(1);i<=m;++i){
            printf("%d ",a[i]);
            if(b[i])printf("/ ");
        }
        putchar('\n');
    }
    return 0;
}
il int fen(int x){int ans(1);
    for(int i(1),j(0);i<=m;++i)
        if(j+a[i]<=x)j+=a[i];
        else j=a[i],++ans;
    return ans;
}
il void read(int &x){
    x^=x;ri char c;while(c=getchar(),c<'0'||c>'9');
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
}

Guess you like

Origin www.cnblogs.com/a1b3c7d9/p/11403105.html