題意: 有4種操作,你需要用最少的操作使得0變成n.
- .
反過來考慮這個問題,
有個顯然的性質:
最優情況下,對於n,經過若干次後再除以,得到的值,一定滿足.
因爲如果,那麼先除再肯定更快.
對於,同理.
再來一個性質:.
然後狀態複雜度大概:.
暴力出奇跡!
#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define gc getchar()
using namespace std;
typedef long long ll;
template<class o> void qr(o&x) {
char c=gc; x=0; int f=1;
while(!isdigit(c)){if(c=='-')f=-1; c=gc;}
while(isdigit(c))x=x*10+c-'0',c=gc;
x*=f;
}
int T;
ll n,a,b,c,d;
map<ll,ll> s;
ll f(ll n) {
if(s.count(n)) return s[n];
ll res=n<1e18/d?n*d:(ll)1e18;
ll l1=(n/2)*2,r1=((n+1)/2)*2;
ll l2=(n/3)*3,r2=((n+2)/3)*3;
ll l3=(n/5)*5,r3=((n+4)/5)*5;
res=min(res,(n-l1)*d+f(l1/2)+a);
res=min(res,(r1-n)*d+f(r1/2)+a);
res=min(res,(n-l2)*d+f(l2/3)+b);
res=min(res,(r2-n)*d+f(r2/3)+b);
res=min(res,(n-l3)*d+f(l3/5)+c);
res=min(res,(r3-n)*d+f(r3/5)+c);
return s[n]=res;
}
int main() {
qr(T); while(T--) {
qr(n); qr(a); qr(b); qr(c); qr(d);
s.clear(); s[0]=0; s[1]=d; printf("%lld\n",f(n));
}
return 0;
}