Input:
5 2 3 102
-3 -1 1 -2 0
Output:
17
ideas: core: enumeration optimization + dichotomy.
For interval addition operations, it must be the most cost-effective
for the entire interval +1; for interval multiplication operations, it must be the most cost-effective to multiply the maximum interval by 2.
For mixing addition and multiplication, it is most cost-effective to do addition first and then multiplication.
Observing the data range s ≤ 1e9, the 31st power of 2 is about the same, so enumerate the number of multiplications and divide the number of additions by two to find the minimum cost.
//二分
//先加再乘
//枚举乘,然后加法二分
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
ll n,a,b;
ll s;
const int N=1e5+10;
ll dp[N];
ll arr[N];
ll qsm(ll a , ll b)
{
ll ans=1,temp=a;
while( b )
{
if( b & 1) ans = (ans * temp );
temp *= temp;
b >>= 1;
}
return ans;
}
bool check( ll y ,ll x)
{
ll maxn=-1e18;
ll sum=0;
//求最大字段和
for( int i=1 ;i<=n ;i++)
{
if( sum < 0) sum=0;
sum += arr[i] + y;
maxn = max ( maxn, sum);
}
if( maxn<=0 ) return false;
//写成1.0 * s qsm(2,x)会爆longlong,
return maxn >=1.0 * s / qsm(2,x );
}
ll cal(int x)
{
ll l = 0 , r = 3*1e9+10;
while( l <= r )
{
ll mid = ( l+r )>>1;
if( check(mid,x) ) r = mid-1;
else l = mid+1;
}
return x * b + l * a;
}
signed main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
cin>>n>>a>>b>>s;
for(int i=1 ;i<=n ;i++)
cin>>arr[i];
ll res=1e18;
//因为乘法最多32次,枚举乘法,二分加法即可
for(int i=0 ;i<=32 ;i++)
{
res = min( res ,cal(i));
}
cout<<res<<endl;
}