输入文件第 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
费用流
用类似于可重复背包删边
注意这坑题慢洗可能比快洗要快(坑哭我)
#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;
}