题目描述
某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初的库存量为零,第n月月底的库存量也为零,问如何安排这n个月订购计划,才能使成本最低?每月月初订购,订购后产品立即到货,进库并供应市场,于当月被售掉则不必付存贮费。假设仓库容量为S。
输入输出格式
输入格式:
第1行:n, m, S (0<=n<=50, 0<=m<=10, 0<=S<=10000)
第2行:U1 , U2 , ... , Ui , ... , Un (0<=Ui<=10000)
第3行:d1 , d2 , ..., di , ... , dn (0<=di<=100)
输出格式:
只有1行,一个整数,代表最低成本
输入输出样例
输入样例#1: 复制
3 1 1000 2 4 8 1 2 4
输出样例#1: 复制
34
题解:
还是一道很裸很裸的题。(怎么办,最近只会刷水题)
思路来的很快,很明显是一道费用流。
1.将源点分别和每个点建边,控制每个点的购买费用。
2.每个点向下一个点建边,控制贮存费用。
3.每个点向汇点建边。
然后跑个费用流就好。
1 //Never forget why you start 2 #include<iostream> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<algorithm> 8 #include<queue> 9 #define inf (2000000000) 10 using namespace std; 11 int n,m,S; 12 struct node{ 13 int next,to,cap,cost; 14 }edge[1005]; 15 int head[1005],size=1; 16 void putin(int from,int to,int cap,int cost){ 17 size++; 18 edge[size].next=head[from]; 19 edge[size].to=to; 20 edge[size].cap=cap; 21 edge[size].cost=cost; 22 head[from]=size; 23 } 24 void in(int from,int to,int cap,int cost){ 25 putin(from,to,cap,cost); 26 putin(to,from,0,-cost); 27 } 28 int pre[1005],vis[1005],dist[1005]; 29 bool bfs(int src,int des){ 30 int i; 31 queue<int>mem; 32 memset(dist,127/3,sizeof(dist)); 33 memset(pre,0,sizeof(pre)); 34 dist[src]=0; 35 mem.push(src); 36 while(!mem.empty()){ 37 int x=mem.front();mem.pop(); 38 for(i=head[x];i!=-1;i=edge[i].next){ 39 int y=edge[i].to; 40 if(edge[i].cap>0&&dist[y]>dist[x]+edge[i].cost){ 41 dist[y]=dist[x]+edge[i].cost; 42 pre[y]=i; 43 mem.push(y); 44 } 45 } 46 } 47 return pre[des]!=0; 48 } 49 int change(int src,int des){ 50 int ans=0,i,flow=inf; 51 for(i=des;i!=src;i=edge[pre[i]^1].to) 52 flow=min(flow,edge[pre[i]].cap); 53 for(i=des;i!=src;i=edge[pre[i]^1].to){ 54 edge[pre[i]].cap-=flow; 55 edge[pre[i]^1].cap+=flow; 56 ans+=edge[pre[i]].cost*flow; 57 } 58 return ans; 59 } 60 int min_cost_flow(int src,int des){ 61 int ans=0; 62 while(bfs(src,des)){ 63 ans+=change(src,des); 64 } 65 return ans; 66 } 67 int main(){ 68 int i,j; 69 memset(head,-1,sizeof(head)); 70 scanf("%d%d%d",&n,&m,&S); 71 for(i=1;i<=n;i++){ 72 scanf("%d",&j); 73 in(i,n+1,j,0); 74 } 75 for(i=1;i<=n;i++){ 76 scanf("%d",&j); 77 in(0,i,inf,j); 78 } 79 for(i=2;i<=n;i++) 80 in(i-1,i,S,m); 81 printf("%d ",min_cost_flow(0,n+1)); 82 return 0; 83 }