某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初的库存量为零,第n月月底的库存量也为零,问如何安排这n个月订购计划,才能使成本最低?每月月初订购,订购后产品立即到货,进库并供应市场,于当月被售掉则不必付存贮费。假设仓库容量为S。
Input
第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)
Output
只有1行,一个整数,代表最低成本
Sample Input
3 1 1000 2 4 8 1 2 4
Sample Output
34
设一个源点S,汇点t;
主要是建边的问题:
从 s 向每个月连一条 flow= inf , cost = di 的边,因为可以无限的进货,每次进货单价费用为 di;
每个月之间连 flow = s, cost = m 的边,总容量最大只能为仓库容量,而单位贮存费用为 m;
最后每个月再向 t 连 flow = ui, cost = 0 的边,因为需求量为 ui ,而销售的花费自然为0;
最后跑一遍 最小费用最大流即可;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 300005
#define inf 0x3f3f3f3f
#define INF 999999999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 20100403
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
inline ll rd() {
ll x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
}
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }
bool vis[maxn];
int n, m, s, t;
int x, y, f, z;
int dis[maxn], pre[maxn], last[maxn], flow[maxn];
int maxflow, mincost;
struct node {
int to, nxt, flow, cost;
}edge[maxn<<2];
int head[maxn], cnt;
queue<int>q;
void addedge(int from, int to, int flow, int cost) {
edge[++cnt].to = to; edge[cnt].flow = flow; edge[cnt].cost = cost;
edge[cnt].nxt = head[from]; head[from] = cnt;
}
bool spfa(int s, int t) {
memset(dis, 0x7f, sizeof(dis)); memset(flow, 0x7f, sizeof(flow));
ms(vis);
q.push(s); vis[s] = 1; dis[s] = 0; pre[t] = -1;
while (!q.empty()) {
int now = q.front(); q.pop(); vis[now] = 0;
for (int i = head[now]; i != -1; i = edge[i].nxt) {
int to = edge[i].to;
if (edge[i].flow > 0 && dis[to] > dis[now] + edge[i].cost) {
dis[to] = dis[now] + edge[i].cost;
pre[to] = now; last[to] = i;
flow[to] = min(flow[now], edge[i].flow);
if (!vis[to]) {
vis[to] = 1; q.push(to);
}
}
}
}
return pre[t] != -1;
}
void maxflow_mincost() {
while (spfa(s, t)) {
int now = t;
maxflow += flow[t]; mincost += flow[t] * dis[t];
while (now != s) {
edge[last[now]].flow -= flow[t];
edge[last[now] ^ 1].flow += flow[t];
now = pre[now];
}
}
}
int main()
{
//ios::sync_with_stdio(false);
cnt = 1; memset(head, -1, sizeof(head));
rdint(n); rdint(m);
int S; rdint(S);
s = 0; t = n + 1;
for (int i = 1; i <= n; i++) {
int U; rdint(U);
addedge(i, t, U, 0); addedge(t, i, 0, 0);
}
for (int i = 1; i <= n; i++) {
int D; rdint(D);
addedge(s, i, inf, D); addedge(i, s, 0, -D);
}
for (int i = 1; i < n; i++) {
addedge(i, i + 1, S, m); addedge(i + 1, i, 0, -m);
}
maxflow_mincost();
cout << mincost << endl;
return 0;
}