AtCoder Grand Contest 044 A Pay to Win 貪心
阿新 • • 發佈:2020-06-02
LINK:Pay to Win
自閉了 比賽的時候推出來正解了 以為複雜度不對 寫完扔了 沒拿map存狀態就扔了23333...
一個T點:在更新map的時候 >不要寫成>= 不然會徒勞的增加複雜度 被這個東西坑了好幾次了。
思路:如果直接從1到n這樣增加 很茫然 不知道要乘什麼。
容易想到倒著做 從n到1這樣。這樣每次就知道到底可以除誰。
容易想到 x-w/d比x/d-w 優。
所以每次先考慮除以什麼 如果要除以2 那麼顯然應該是2的倍數 3,5同理。
然後用map存狀態 可以發現總狀態量是1e5的 所以可以通過。
const ll MAXN=100010; ll T; ll n,A,B,C,D,ans; map<ll,ll>H; priority_queue<pii>q; inline void gx(ll x,ll w) { if(w>=ans)return; if(H.find(x)==H.end())H[x]=w,q.push(mk(x,-w)); else { if(w>=H[x])return; H[x]=w;q.push(mk(x,-w)); } } signed main() { //freopen("1.in","r",stdin); get(T); while(T--) { get(n);get(A);get(B);get(C);get(D); H.clear();q.push(mk(n,0)); ans=INF;H[n]=0; int cnt=0; while(q.size()) { ll x=q.top().F; ll w=-q.top().S; q.pop(); if(w>ans)continue; if(H[x]!=w)continue; //考慮直接減到0 if(INF/D>x)ans=min(ans,D*x+w); if(x%2)gx(x/2,w+D+A),gx(x/2+1,w+D+A); else gx(x/2,w+A); if(x%3)gx(x/3,w+x%3*D+B),gx(x/3+1,w+(3-x%3)*D+B); else gx(x/3,w+B); if(x%5)gx(x/5,w+x%5*D+C),gx(x/5+1,w+(5-x%5)*D+C); else gx(x/5,w+C); //put(++cnt); } putl(ans); } return 0; }