1233: [Usaco2009Open] haystack tower

Portal

The feeling of being the do not a good practice, considering engage in reverse

Easy to think of greedy, greedy each layer selected minimum width, and then found $ WA $ a ...

 

For a start, it can sometimes make multiple selections under a layer of smaller width

Then there is a magical conclusion, the highest one is the underlying program must have the narrowest program

prove:

Consider all the blocks in the order in a row and is divided into sections, each section indicates a layer, the underlying assumption is a narrowest FIG solution

Suppose there is a better solution, so that the bottom is wider:

 Then according to the principles of the drawer, the intermediate section must have at least blue red two dividing lines

You might find such a position, labeled as $ x, y $:

Clearly then we can construct a new program, so that the upper layers of the red after the division by $ Y $, the following layers divided by blue before $ P $, the intermediate layer is a $ [p, y] $

Because $ [p, y] $ greater than $ $ [x, y], so the upper layer also must be smaller than $ [p, y] $, empathy $ [p, y] $ must be smaller than $ [p, q] $ , the lower layer must be greater than $ [p, y] $

Then we found that the new program structure becomes more layers, the bottom is still the narrowest program

So to prove the underlying program must have the narrowest one is the optimal solution

DP can then $ a $, set $ f [i] $ denotes considered complete when $ i, n $ block, the narrowest width of the bottom, while maintaining $ g [i] $ denotes End considered $ i, n $ of block, the maximum number of layers at the bottom of the narrowest

Clearly then enumerate all $ j> i $, transferred $ f [i] = min (sum [j-1] -sum [i]) $ ($ sum $ prefix and the block width) and satisfy $ sum [j -1] -sum [i]> = f [j] $

Decision is then found that for two $ k, j $ where $ k> j $, $ k $ $ will be better than if only $ j $ j $ case not legal, i.e. $ sum [j-1] -sum [i ] <f [j] $

And because $ sum [i] $ monotonically increasing, so the legal decision point will become smaller and smaller, so with a wave of monotonous queue maintenance can be done $ O (n) $ has shifted

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
typedef long long ll;
using namespace std;
inline ll read()
{
    ll x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=2e5+7;
int n,a[N],ans,g[N],Q[N];
ll sum[N],f[N];
// f[i]=sum[j-1]-sum[i-1] j>i sum[j-1]-sum[i-1]>=f[j]
// sum[i-1]<=sum[j-1]-f[j]
// k>j sum[k-1]-f[k]>sum[j-1]-f[j]
int main()
{
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    int L=1,R=1; Q[1]=n+1;
    for(int i=n;i;i--)
    {
        while(L<R&&sum[Q[L+1]-1]-sum[i-1]>=f[Q[L+1]]) L++;//队列中越后面的位置越优
        f[i]=sum[Q[L]-1]-sum[i-1]; g[i]=g[Q[L]]+1;
        while(L<=R&&sum[Q[R]-1]-f[Q[R]]<=sum[i-1]-f[i]) R--;
        Q[++R]=i;
    }
    printf("%d\n",g[1]);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/LLTYYC/p/11331369.html