#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define maxn 2005
#define INF 9223372036854775807LL
typedef long long ll;
struct Edge {
ll v, flow, cost, next;
};
ll N;
ll r[maxn];
ll p, m, f, n, s;
void input() {
scanf("%lld", &N);
for (ll i = 1; i <= N; i++) {
scanf("%lld", r + i);
}
scanf("%lld %lld %lld %lld %lld", &p, &m, &f, &n, &s);
}
struct Graph {
Edge edge[(6 * maxn) * 2];
ll head[2 * maxn];
ll cnt = 1;
void __add_edge(ll u, ll v, ll flow, ll cost) {
cnt++;
edge[cnt].v = v;
edge[cnt].flow = flow;
edge[cnt].cost = cost;
edge[cnt].next = head[u];
head[u] = cnt;
}
void add_edge(ll u, ll v, ll flow, ll cost) {
__add_edge(u, v, flow, cost);
__add_edge(v, u, 0, -cost);
}
ll s, t;
ll min(ll a, ll b) {
return a < b ? a : b;
}
ll max_flow = 0, min_cost = 0;
// 经过的总流量
ll flow_[2 * maxn];
// 经过的总价格
ll cost_[2 * maxn];
// 记录路径
ll pre[2 * maxn];
ll last[2 * maxn];
bool inq[2 * maxn];
bool spfa() {
memset(cost_, 0x3f, sizeof(cost_));
cost_[s] = 0;
queue < ll > q;
q.push(s);
memset(inq, false, sizeof(inq));
inq[s] = true;
memset(flow_, 0, sizeof(flow_));
flow_[s] = INF;
while (!q.empty()) {
ll u = q.front(); q.pop();
inq[u] = false;
for (ll i = head[u]; i; i = edge[i].next) {
ll v = edge[i].v, f = edge[i].flow, c = edge[i].cost;
if (f > 0 && cost_[v] > cost_[u] + c) {
cost_[v] = cost_[u] + c;
flow_[v] = min(flow_[u], f);
pre[v] = u;
last[v] = i;
if (!inq[v]) {
q.push(v);
inq[v] = true;
}
}
}
}
return cost_[t] != 0x3f3f3f3f3f3f3f3f;
}
void mcmf() {
while (spfa()) {
max_flow += flow_[t];
min_cost += flow_[t] * cost_[t];
ll now = t;
while (now != s) {
edge[last[now]].flow -= flow_[t];
edge[last[now] ^ 1].flow += flow_[t];
now = pre[now];
}
}
}
void init() {
s = 0;
t = 2 * N + 1;
// 每天晚上获得脏毛巾
for (ll i = 1; i <= N; i++) {
add_edge(s, i + N, r[i], 0);
}
// 每天早上取出干净的毛巾
for (ll i = 1; i <= N; i++) {
add_edge(i, t, r[i], 0);
}
// 每天晚上到下一天晚上
for (ll i = 1; i < N; i++) {
add_edge(i + N, i + N + 1, INF, 0);
}
// 送到快洗部
for (ll i = 1; i <= N - m; i++) {
add_edge(i + N, i + m, INF, f);
}
// 送到慢洗部
for (ll i = 1; i <= N - n; i++) {
add_edge(i + N, i + n, INF, s);
}
// 购买毛巾
for (ll i = 1; i <= N; i++) {
add_edge(s, i, INF, p);
}
}
} g;
signed main() {
input();
g.init();
g.mcmf();
printf("%lld", g.min_cost);
return 0;
}
样例过了
提交 30 分