标签:
题目这么说的:
一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N)。餐厅可以从三种途径获得餐巾。
- 购买新的餐巾,每块需p分;
- 把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p)。如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此。
- 把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f)。
在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部。在每天开始时,餐厅必须决定是否购买新餐巾及多少,使洗好的和新购的餐巾之和满足当天的需求量Ri,并使N天总的费用最小。
挺有趣的题,至少还需要稍微思考思考。。考虑用最小费用最大流。
这样建完图跑最小费用最大流就OK了。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1<<30) 7 #define MAXN 444 8 #define MAXM 444*888 9 struct Edge{ 10 int u,v,cap,cost,next; 11 }edge[MAXM]; 12 int head[MAXN]; 13 int NV,NE,vs,vt; 14 15 void addEdge(int u,int v,int cap,int cost){ 16 edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost; 17 edge[NE].next=head[u]; head[u]=NE++; 18 edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost; 19 edge[NE].next=head[v]; head[v]=NE++; 20 } 21 bool vis[MAXN]; 22 int d[MAXN],pre[MAXN]; 23 bool SPFA(){ 24 for(int i=0;i<NV;++i){ 25 vis[i]=0; 26 d[i]=INF; 27 } 28 vis[vs]=1; 29 d[vs]=0; 30 queue<int> que; 31 que.push(vs); 32 while(!que.empty()){ 33 int u=que.front(); que.pop(); 34 for(int i=head[u]; i!=-1; i=edge[i].next){ 35 int v=edge[i].v; 36 if(edge[i].cap && d[v]>d[u]+edge[i].cost){ 37 d[v]=d[u]+edge[i].cost; 38 pre[v]=i; 39 if(!vis[v]){ 40 vis[v]=1; 41 que.push(v); 42 } 43 } 44 } 45 vis[u]=0; 46 } 47 return d[vt]!=INF; 48 } 49 int MCMF(){ 50 int res=0; 51 while(SPFA()){ 52 int flow=INF,cost=0; 53 for(int u=vt; u!=vs; u=edge[pre[u]].u){ 54 flow=min(flow,edge[pre[u]].cap); 55 } 56 for(int u=vt; u!=vs; u=edge[pre[u]].u){ 57 edge[pre[u]].cap-=flow; 58 edge[pre[u]^1].cap+=flow; 59 cost+=flow*edge[pre[u]].cost; 60 } 61 res+=cost; 62 } 63 return res; 64 } 65 int need[222]; 66 int main(){ 67 freopen("napkin.in","r",stdin); 68 freopen("napkin.out","w",stdout); 69 int n,p,a,b,x,y; 70 scanf("%d",&n); 71 for(int i=1; i<=n; ++i){ 72 scanf("%d",need+i); 73 } 74 scanf("%d%d%d%d%d",&p,&a,&b,&x,&y); 75 vs=0; vt=n*2+1; NV=vt+1; NE=0; 76 memset(head,-1,sizeof(head)); 77 for(int i=1; i<=n; ++i){ 78 addEdge(vs,i+n,INF,p); 79 addEdge(i+n,vt,need[i],0); 80 addEdge(vs,i,need[i],0); 81 for(int j=i+a; j<=n; ++j) addEdge(i,j+n,INF,b); 82 for(int j=i+x; j<=n; ++j) addEdge(i,j+n,INF,y); 83 } 84 printf("%d",MCMF()); 85 return 0; 86 }
标签:
原文地址:http://www.cnblogs.com/WABoss/p/5364883.html