• [补档]餐巾


    餐巾

    题目

    一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N)。餐厅可以从三种途径获得餐巾。
    (1)购买新的餐巾,每块需p分;
    (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p)。如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此。
    (3)把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f)。
    在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部。在每天开始时,餐厅必须决定是否购买新餐巾及多少,使洗好的和新购的餐巾之和满足当天的需求量Ri,并使N天总的费用最小。

    INPUT

    输入文件共 3 行,第 1 行为总天数;
    第 2 行为每天所需的餐巾块数;
    第 3 行为每块餐巾的新购费用 p ,快洗所需天数 m ,快洗所需费用 f ,慢洗所需天数 n ,慢洗所需费用 s 。

    OUTPUT

    一行,最小的费用

    SAMPLE

    INPUT

    3
    3 2 4
    10 1 6 2 3

    OUTPUT

    64

    解题报告

    首先,每天的餐巾分为两种情况,新买的和原来的。
    每天作为一个点,由S向其连边,容量为Ri,花费为0。
    每天可以向T连边,容量为INF,花费为p,每天都可以购买餐巾无数次。
    将每天用过的餐巾在新建一层点,由于分配去快洗和慢洗的餐巾总数有限制,并非分别有限制,所有这两种无需再分开,这层点分别向T建边,容量为Ri,花费为0,限制总容量。
    使用快洗的餐巾,由i向(i+m+N)’建边,容量为INF,花费为f,慢洗同理,花费分别建边。
    但第i-m天洗完后的餐巾也可以供第i天以后使用。所以再由i向i+1建边,容量为INF,花费为0。这样第i天就能使用到以前所有可以使用的洗完的餐巾了。
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<queue>
     5 using namespace std;
     6 struct edge{
     7     int e,n,flow,cost;
     8 }a[20010];
     9 int pre[410],tot;
    10 inline void insert(int s,int e,int flow,int cost){
    11     a[tot].e=e;
    12     a[tot].flow=flow;
    13     a[tot].cost=cost;
    14     a[tot].n=pre[s];
    15     pre[s]=tot++;
    16 }
    17 int S(0),T;
    18 int N,p,m,f,n,s;
    19 int r[201];
    20 int flow(0),ans(0),inf(0x7fffffff);
    21 inline void build(){
    22     for(int i=1;i<=N;i++){
    23         insert(S,i,r[i],0),insert(i,S,0,0);
    24         insert(S,i+N,inf,p),insert(i+N,S,0,-p);
    25         insert(i+N,T,r[i],0),insert(T,i+N,0,0);
    26         if(i+m<=N)
    27             insert(i,i+m+N,inf,f),insert(i+m+N,i,0,-f);
    28         if(i+n<=N)
    29             insert(i,i+n+N,inf,s),insert(i+n+N,i,0,-s);
    30         if(i!=N)
    31             insert(i,i+1,inf,0),insert(i+1,i,0,0);
    32     }
    33 }
    34 int dis[410],fa[410],path[410];
    35 inline bool bfs(){
    36     memset(dis,30,sizeof(dis));
    37     memset(fa,-1,sizeof(fa));
    38     queue<int>q;
    39     q.push(S);
    40     dis[S]=0;
    41     while(!q.empty()){
    42         int k(q.front());
    43         q.pop();
    44         for(int i=pre[k];i!=-1;i=a[i].n){
    45             int e(a[i].e);
    46             if(a[i].flow&&dis[e]>dis[k]+a[i].cost){
    47                 dis[e]=dis[k]+a[i].cost;
    48                 fa[e]=k;
    49                 path[e]=i;
    50                 q.push(e);
    51             }
    52         }
    53     }
    54     if(fa[T]==-1)
    55         return false;
    56     return true;
    57 }
    58 inline void dinic(){
    59     while(bfs()){
    60         int f(inf);
    61         for(int i=T;i!=S;i=fa[i])
    62             if(a[path[i]].flow<f)
    63                 f=a[path[i]].flow;
    64         flow+=f;
    65         ans+=dis[T]*f;
    66         for(int i=T;i!=S;i=fa[i]){
    67             a[path[i]].flow-=f;
    68             a[path[i]^1].flow+=f;
    69         }
    70     }
    71 }
    72 inline int gg(){
    73     freopen("napkin.in","r",stdin);
    74     freopen("napkin.out","w",stdout);
    75     memset(pre,-1,sizeof(pre));
    76     scanf("%d",&N);
    77     T=(N<<1)+1;
    78     for(int i=1;i<=N;i++)
    79         scanf("%d",&r[i]);
    80     scanf("%d%d%d%d%d",&p,&m,&f,&n,&s);
    81     build();
    82     dinic();
    83     printf("%d",ans);
    84     return 0;
    85 }
    86 int K(gg());
    87 int main(){;}
    View Code
  • 相关阅读:
    RabbitMQ实战(文摘)
    dex2jar 和 jd-gui 的安装与使用(转)
    asp.net core跨平台开发从入门到实战文摘
    hashCode() 和equals() 区别和作用(转)
    B+树和LSM比较(转)
    C#并发集合(转)
    文档docsify
    如何熟悉一个系统?(内含知识大图)
    新浪微博应对弹性扩容的架构演进
    iftop非交互式监控流量来源和去向
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7277693.html
Copyright © 2020-2023  润新知