zoukankan      html  css  js  c++  java
  • [HNOI2001]软件开发

    题目描述

    某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的 服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用。消毒方式有两种,A种方式的消毒需要 a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用);而且f>fA>fB。公司经理正在规划在 这n天中,每天买多少块新毛巾、每天送多少块毛巾进行A种消毒和每天送多少块毛巾进行B种消毒。当然,公司经理希望费用最低。

    你的任务就是:为该软件公司计划每天买多少块毛巾、每天多少块毛巾进行A种消毒和多少毛巾进行B种消毒,使公司在这项n天的软件开发中,提供毛巾服务的总费用最低。

    输入输出格式

    输入格式:

    第1行为n,a,b,f,fA,fB.

    第2行为n1,n2,……,nn. (注:1≤f,fA,fB≤60,1≤n≤1000)

    输出格式:

    最少费用

    输入输出样例

    输入样例#1: 复制
    4  1  2  3  2  1                         
    8  2  1  6  
    
    输出样例#1: 复制
    38

    建立附加源点和汇点S和T

    
    

    1. 源点到第i天的入点连容量ni费用为0的边

    
    

    2. 第i天的出点到汇点连容量ni费用为0的边

    
    

    3. 源点到第i天的出点连容量为INF费用为f的边

    
    

    4. 第i天的入点到第i+a+1(i+b+1)天的出点连容量为INF费用为fa(fb)的边

    
    

    5. 第i天的入点到第i+1天的入点连容量为INF费用为0的边

    S连出的边表示这一天会剩下ni个脏布,连向T表示这一天要用ni个布

    一天用完的ni个布,可以由a(b)方式给第i+a+1(i+b+1)天,也可以不洗,留到下一天再洗

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 struct Node
     8 {
     9     int next,to,c,dis,u;
    10 }edge[200001];
    11 int num=1,head[5001],inf=2e9,dis[5001],pre[5001];
    12 long long ans;
    13 int d[5001],n,a,b,fa,fb,f;
    14 bool vis[5001];
    15 void add(int u,int v,int c,int d)
    16 {
    17     num++;
    18     edge[num].next=head[u];
    19     head[u]=num;
    20     edge[num].to=v;
    21     edge[num].dis=d;
    22     edge[num].c=c;
    23     edge[num].u=u;
    24     num++;
    25     edge[num].next=head[v];
    26     head[v]=num;
    27     edge[num].to=u;
    28     edge[num].dis=-d;
    29     edge[num].c=0;
    30     edge[num].u=v;
    31 }
    32 bool SPFA()
    33 {int INF,i;
    34     memset(pre,-1,sizeof(pre));
    35     memset(vis,0,sizeof(vis));
    36     memset(dis,127/3,sizeof(dis));
    37     INF=dis[0];
    38     dis[0]=0;
    39     queue<int>Q;
    40     Q.push(0);
    41     while (Q.empty()==0)
    42     {
    43         int u=Q.front();
    44         Q.pop();
    45         vis[u]=0;
    46         for (i=head[u];i;i=edge[i].next)
    47         {
    48             int v=edge[i].to;
    49             if (edge[i].c&&dis[v]>dis[u]+edge[i].dis)
    50             {
    51                 dis[v]=dis[u]+edge[i].dis;
    52                 pre[v]=i;
    53                 if (vis[v]==0)
    54                 {
    55                     vis[v]=1;
    56                     Q.push(v);
    57                 }
    58             }
    59         }
    60     }
    61     if (dis[2*n+1]==INF) return 0;
    62     return 1;
    63 }
    64 void change()
    65 {int i;
    66     int T=2*n+1;
    67         int minf=inf;
    68         for (i=pre[T];i!=-1;i=pre[edge[i].u])
    69         {
    70             minf=min(minf,edge[i].c);
    71         }
    72         for (i=pre[T];i!=-1;i=pre[edge[i].u])
    73         {
    74             edge[i].c-=minf;
    75             edge[i^1].c+=minf;
    76         }
    77     ans+=minf*dis[T];
    78 }
    79 int main()
    80 {int i;
    81     cin>>n>>a>>b>>f>>fa>>fb;
    82     for (i=1;i<=n;i++)
    83     scanf("%d",&d[i]);
    84     for (i=1;i<=n;i++)
    85     add(0,i,d[i],0),add(i+n,2*n+1,d[i],0),add(0,i+n,inf,f);
    86     for (i=1;i<=n-1;i++)
    87     add(i,i+1,inf,0);
    88     for (i=1;i<=n;i++)
    89     {
    90         if (i+a+1<=n) add(i,i+a+1+n,inf,fa);
    91         if (i+b+1<=n) add(i,i+b+1+n,inf,fb);
    92     }
    93     while (SPFA()) change();
    94     cout<<ans;
    95 }
  • 相关阅读:
    linux命令行
    mybatis中#{}和${}的区别
    @InitBinder的作用
    mui 实用封装销毁页面
    【SQLite】简单的基本使用步骤
    常用的一些操作方法
    【HttpWeb】Post和GET请求基本封装
    【接口验证】特性验证参数
    小谈单例模式
    vs下开端口直接调试iis
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8094175.html
Copyright © 2011-2022 走看看