Luo Gu P4480 [[BJWC2018] napkin plan Problem

This question and network flow \ (24 \) title of napkins plan really is not the same, \ ([\) \ (BJWC \) \ (2018 \) \ (] \) greater range of data napkins planning problem.

A restaurant in successive \ (n \) days, every day the number of napkins required vary. Assume that the first \ (I \) Day \ ((\) \ (I \) \ (= \) \ (. 1 \) \ (, \) \ (2 \) \ (, \) \ (... \) \ (, \) \ (n-\) \ () \) requires \ (RI \) block napkins. The restaurant can buy new napkins at any time, the cost of each napkin is \ (the p-\) .

Used the old napkin, you will need to re-use after cleaning. An old napkin to clean the shop \ (A \) , need to wait \ (m1 \) days to get a new napkin, at a cost of $ c1 $; an old napkin to clean the shop $ B $, $ need to wait m2 $ days to get a new napkin, at a cost of $ c2 $.

For example, a k-th angel napkins used to store $ A $ cleaning cleaning, can be used at the $ k $ $ + $ $ m1 $ days.

For 50% of the data, we have a very classic network flow approach: napkins planning problem .

But after the expansion of the scale of the data obviously it can not be solved with a network flow.

Two cases:

\ (1 \) . Quick wash shop is more expensive:

Taking into account before buying and buy the napkins and the answers will not affect the process, and when to buy napkins $ c $ bar reaches the optimal solution, obviously $ c $ $ + $ $ k $ cost more than $ c $ $ + $ $ k $ $ + $ $ 1 $ to spend less.

And a license is not difficult emotional cost ck ck-1 than to spend less (use napkins quick wash shop several times in the optimal situation makes money increases).

So we can solve the three points.

The cheapest apparently the first to use the new towels until no more time with slow wash shop, come quick wash shop using the worst answer, use what you can to maintain the queue (That said, is quite disgusting, I at another tune code for just over 3h, may now let me explain the code is interpreted not understand.)

2. A quick wash points cheaper:

Almost wash, this is obvious.

This is a lovely code

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
const int INF=2147483647;
inline int read(){
    int X=0,w=1;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')X=(X<<1)+(X<<3)+ch-'0',ch=getchar();
    return X*w;
}
int t[N],num[N],q[N],cnt,d,n1,n2,c1,c2,tc;
int sn,sm,so,en,em,eo;
inline void add(int x,int p){
    q[en]=x;num[en++]=p;
}
int f(int k){
    sn=sm=so=en=em=eo=0;
    int ans=(tc-c2)*k;
    add(-2000000,k);
    for(int i=1;i<=d;i++){
        int j=t[i];
        while(sn!=en&&i-q[sn]>=n1){
            num[em]=num[sn];
            q[em++]=q[sn++];
        }
        while(sm!=em&&i-q[sm]>=n2){
            num[eo]=num[sm];
            q[eo++]=q[sm++];
        }
        while(j>0){
            if(so!=eo){
                if(num[eo-1]>j){
                    ans+=c2*j;
                    num[eo-1]-=j;
                    break;
                }
                else{
                    ans+=c2*num[eo-1];
                    j-=num[eo-1];
                    eo--;
                }
            }
            else if(sm!=em){
                if(num[em-1]>j){
                    ans+=c1*j;
                    num[em-1]-=j;
                    break;
                }
                else{
                    ans+=c1*num[em-1];
                    j-=num[em-1];
                    em--;
                }
            }
            else return INF;
        }
        add(i,t[i]);
    }
    return ans;
}
int sfen(int l,int r){
    while(233){
        if(r-l<=2){
            int m=INF;
            for(int i=l;i<r;i++)m=min(m,f(i));
            return m;
        }
        int mid1=l+(r-l)/3,mid2=l+2*(r-l)/3;
        int a=f(mid1);
        if(a!=INF&&a<=f(mid2))r=mid2;
        else l=mid1;
    }
}
int main(){
    d=read(),n1=read(),n2=read(),c1=read(),c2=read(),tc=read();
    if(n1>n2){swap(n1,n2);swap(c1,c2);}
    if(c1<=c2)n2=2000001,c2=101;
    int tsum=0;
    for(int i=1;i<=d;i++){
        t[i]=read();tsum+=t[i];
    }
    printf("%d\n",sfen(0,tsum+1));
    return 0;
}

Guess you like

Origin www.cnblogs.com/errichto/p/11317278.html
Recommended