루오 구 P4480 [BJWC2018] 냅킨 계획 문제

이 질문에 네트워크 흐름 \ (24 \) 냅킨의 제목이 정말 동일하지 않습니다 계획 \ ([\) \ (BJWC \) \ (2018 \) \ (] \) 문제를 계획 데이터 냅킨의 큰 범위.

연속의 레스토랑 \ (n \) 일, 냅킨의 번호 필요 매일 다릅니다. 가정이 제 \ (I는 \) 의 날 (\ (\) \ (I \) \ (= \) \ (. 1 \) \ (\) \ (2 \) \ (\) \ (... \) \ (\) \ (N- \) \ () \) 필요 \ (RI \) 블록 냅킨. 레스토랑은 언제든지 새로운 냅킨을 구입하실 수 있습니다, 각 냅킨의 비용은 \ (ρ-의 \) .

이전 냅킨을 사용, 당신은 다시 사용하기 위해 청소 후해야합니다. 옛날 냅킨이 가게 청소 \ (A \) , 기다릴 필요 (M1의 \) \ $의 (C1)의 $의 비용으로, 새로운 냅킨을 얻는 일, 오래된 냅킨을 가게 $ B 형 $ 청소를, $ 필요가 대기 m2 $의 일 $의 C2에 $의 비용으로, 새로운 냅킨을 얻을 수 있습니다.

예를 들어, k 번째 천사 냅킨 $ A $ 세정 청소를 저장하는 데 사용하는 $ K $ $ + $ $ M1 $ 일에 이용할 수있다.

데이터의 50 %를 들면, 우리는 매우 고전적인 네트워크 흐름 방식을 가지고 : 냅킨이 문제를 계획 .

그러나 데이터의 규모의 확장 후 분명히는 네트워크 흐름을 해결할 수 없습니다.

두 경우 :

\ (1 \) . 빠른 세척 가게는 더 비싸다 :

구입하기 전에 고려와 냅킨을 구입하고 답변하는 과정에 영향을 미치지 않습니다 때, 그리고 냅킨에게 $ C 형 $ 줄을 구입하는 것은 분명히, $ C $ $ + $ $ 케이 $ 비용보다 $ C $ $ +보다 최적의 솔루션에 도달 $ $ K $ $ + $ $ 1 $를 적게 지출합니다.

그리고 라이센스가 어려운 감정 비용 CK CK-1보다 (돈이 증가하게 최적의 상황에서 사용하는 냅킨 빠른 세척 가게 여러 번) 이하를 지출하지 않는 것입니다.

그래서 우리는 세 가지 점을 해결할 수 있습니다.

느린 세척 가게에 더 이상 시간까지 새 수건을 사용하는 것이 가장 싼 분명히 첫 번째, 최악의 대답을 사용하여 빠른 세척 가게 와서, 당신이 대기열을 (즉, 아주 역겨운 말했다 유지하기 위해 할 수있는 사용, I 단지 3 시간 이상에 대한 또 다른 조정 코드, 지금 내가 코드를 이해하지 해석을 설명 할 수 있습니다.)

2. 빠른 세척 포인트 저렴 :

거의이 분명하다, 씻어.

이 사랑스러운 코드

#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;
}

추천

출처www.cnblogs.com/errichto/p/11317278.html