#include<bits/stdc++.h>
using namespace std;
using ll=long long;
// 输入参数:n=数组长度,p=加x的代价,x=每次加的数值,q=减y的代价,y=每次减的数值
ll n,p,x,q,y;
/**
* 状态结构体:表示Dijkstra算法中的一个状态
* ans:到达当前状态的总代价(核心优化目标:最小化该值)
* mod:当前数组总和对n取余的结果(状态核心:仅关心余数,而非总和,压缩状态空间)
* 重载<运算符:实现优先队列的小顶堆逻辑(代价越小的状态优先级越高,先弹出)
*/
struct A{
ll ans,mod;
// 算法思想:定义"优先级规则"——ans大的状态优先级低(小顶堆)
bool operator<(const A& other) const {
return ans > other.ans; // 优先队列默认是大顶堆,此逻辑反转后实现小顶堆
}
};
ll sum_m=0; // 数组总和的余数
ll ans=-1; // 最终答案:最小代价,初始化为-1
unordered_set<ll>s;// 记录已处理过的余数(出队时标记,避免重复处理最优状态)
// 优先队列(Dijkstra核心):存储状态,按代价从小到大弹出(小顶堆)
priority_queue<A> Q;
/**
* 算法核心:基于Dijkstra的优先队列BFS
* 问题转化:找从初始余数sum到余数0的最短路径(路径权值为操作代价)
* 状态转移:加x(代价p)、减y(代价q),状态为余数(0~n-1,状态空间有限)
*/
void bfs() {
// 步骤1:初始化初始状态
A t;
t.ans=0; // 初始代价为0(未执行任何操作)
t.mod=sum_m; // 初始状态:数组总和的余数
Q.push(t); // 初始状态入队
// 步骤2:Dijkstra核心循环——优先处理代价最小的状态
while(!Q.empty()) {
// 步骤2.1:弹出当前代价最小的状态(小顶堆保证)
A t=Q.top();
Q.pop();
// 步骤2.2:判重(核心优化):该余数已处理过(最优代价已找到),直接跳过
// 算法思想:出队时判重,而非入队时——保证所有路径都能入队,仅跳过已确定最优的状态
if(s.find(t.mod)!=s.end()) continue;
// 步骤2.3:标记该余数为已处理,避免后续重复处理
s.insert(t.mod);
// 步骤2.4:终止条件:找到目标状态(余数为0),直接返回当前代价(小顶堆保证是最小代价)
if(t.mod==0) {
ans=t.ans;
return;
}
// 步骤2.5:状态转移1:执行"加x"操作
A t1=t;
t1.ans+=p; // 累加操作代价p
t1.mod=(t.mod + x) % n; // 计算新余数(模n压缩状态)
if(t1.mod < 0) t1.mod += n; // 避免负数余数(保证余数在0~n-1)
// 步骤2.6:状态转移2:执行"减y"操作
A t2=t;
t2.ans+=q; // 累加操作代价q
t2.mod=(t.mod - y) % n; // 计算新余数
if(t2.mod < 0) t2.mod += n; // 避免负数余数
// 步骤2.7:新状态入队(不判重)
// 算法思想:入队时不判重,由堆的优先级保证先处理最优状态,出队时再判重
Q.push(t1);
Q.push(t2);
}
}
int main(){
// 输入加速:关闭同步,提升cin/cout速度
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
// 步骤1:输入参数和数组
cin>>n>>p>>x>>q>>y;
for(ll i=1;i<=n;i++){
ll t;
cin>>t;
sum_m+=t; // 计算数组总和
}
// 步骤2:初始校验:如果总和已能被n整除,直接输出0(无需任何操作)
if(sum_m%n==0){
cout<<0;
return 0;
}else{
sum_m%=n; // 压缩为余数(仅关心余数,不关心总和)
if(sum_m < 0) sum_m += n; // 保证余数非负
}
// 步骤3:调用Dijkstra算法求解最小代价
bfs();
// 步骤4:输出结果:找到则输出最小代价,否则输出-1(无解)
cout<<ans;
return 0;
}