superoj441 餐巾计划

来源:互联网 发布:知商金融排名 编辑:程序博客网 时间:2024/04/28 12:05

题目描述

输入格式

输入文件第 1 行有 6 个正整数 N,p,m,f,n,s。其中 N 是要安排餐巾使用计划的天数;p 是每块新餐巾的费用;m 是快洗部洗一块餐巾需用天数;f 是快洗部洗一块餐巾需要的费用;n 是慢洗部洗一块餐巾需用天数;s 是慢洗部洗一块餐巾需要的费用。数据范围如下:1≤N≤800,1≤p≤50,1≤m≤20, 1≤f≤20,1≤n≤20,1≤s≤10。
接下来的 N 行是餐厅在相继的 N 天里,每天需用的餐巾数(每个数不超过500)。

输出格式

输出餐厅在相继的 N 天里使用餐巾的最小总花费。

样例数据 1

输入  [复制]

3 10 2 3 3 2 


7

输出

145

费用流

用类似于可重复背包删边

注意这坑题慢洗可能比快洗要快(坑哭我)

#include<cmath>#include<ctime>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<iostream>#include<algorithm>#include<queue>#include<vector>using namespace std;struct node{   int to;   int next;   int liu;   int cost;   int from;};node bian[1300000];int first[40010];int dis[40010];int xuqiu[40010]; int n,p,m,f,z,s;  //p新餐巾费用 m快洗time f快洗费用 z慢洗time s慢洗费用  int size;queue <int> q;bool exsit[40000];int zcost,zflow;int pre[40000];void inser(int a,int b,int liu,int cost){size++;bian[size].to=b;bian[size].next=first[a];first[a]=size;bian[size].liu=liu;    bian[size].from=a;    bian[size].cost=cost;}void init(){int i,j;    scanf("%d%d%d%d%d%d",&n,&p,&m,&f,&z,&s);for(i=1;i<=n;i++)      {         scanf("%d",&xuqiu[i]);    }    for(i=1;i<=n;i++)     {     inser(0,i,xuqiu[i],0);     inser(i,0,0,0);      }    for(i=1;i<=n;i++)      {      inser(n+i,2*n+1,xuqiu[i],0);      inser(2*n+1,n+i,0,0);  }        for(i=1;i<n;i++)      {      inser(i,i+1,10000000,0);      inser(i+1,i,0,0);  }             for(i=1;i<=n;i++)      {          if(i+m<=n)        {inser(i,i+n+m,10000000,f);        inser(i+n+m,i,0,-f);        }        if(i+z<=n)        {inser(i,i+n+z,10000000,s);        inser(i+n+z,i,0,-s);        }inser(0,n+i,10000000,p);inser(n+i,0,0,-p);    }    inser(4*n,0,100000000,0);}bool spfa(){while(!q.empty()) q.pop();    memset(dis,127,sizeof(dis));    memset(exsit,false,sizeof(exsit));    memset(pre,-1,sizeof(pre));    pre[0]=size;   dis[0]=0;   exsit[0]=true;q.push(0);while(!q.empty())  {   int u=q.front();   q.pop();   exsit[u]=false;   for(int i=first[u];i!=0;i=bian[i].next)     {        int d=bian[i].to;        if(bian[i].liu!=0&&dis[d]>dis[u]+bian[i].cost)           {              dis[d]=dis[u]+bian[i].cost;     pre[d]=i;    if(!exsit[d])    {     exsit[d]=true;    // if(exsit[n*2+1]) return true;     q.push(d);   }     }   }  }    if(dis[2*n+1]>1000000000) return false;return true;}int flow_(){    int flow;while(spfa())      {      flow=0x7fffffff;      for(int i=pre[2*n+1];bian[i].from!=4*n;i=pre[bian[i].from])        {         if(bian[i].liu<flow) flow=bian[i].liu;  }      for(int i=pre[2*n+1];bian[i].from!=4*n;i=pre[bian[i].from])        {          bian[i].liu-=flow;          bian[i+1].liu+=flow;      zcost+=flow*bian[i].cost;     }        zflow+=flow;   } return zcost; }int main(){  // freopen("lx.in","r",stdin); //  freopen("lx.out","w",stdout);   int i,j,k;      init();   int ans=flow_();   cout<<ans;   //cout<<zflow<<" ";  // cout<<size;   return 0;}


0 0