2018.09.24 塔(搜尋)
阿新 • • 發佈:2018-12-11
描述
小A想搭一個體積不超過m的塔,他有各種大小的立方積木,比如邊長為a的積木,體積為a^3,現在小A需要你給一個X,每次小A會用一個體積不超過X的最大積木,依次到搭好為止,現在他想最大化積木的個數,同時在積木個數最大的情況下使X最大
輸入
一行一個數m
輸出
一行兩個數,最多積木數以及x
樣例輸入
48
樣例輸出
9 42
提示
【樣例解釋】
X=23或42都是9次,42 = 3^3 + 2^3 + 7*1^3
【資料範圍】
30%:m<=10^5 50%:m<=10^10 100%:m<=10^15
一道簡單搜尋。 每次遞迴的時候找到最大的 a 使得 a^3 不超過 m。 那麼這時接下來X的第一塊積木的邊長可以在1~a之間。 但是可以證明接下來 X 的第一塊積木必然為 a或 a-1。 因為選長度為的不如選的優秀。 每次 遞迴的時候m 都會變成m^(2/3)。 這樣搜一搜就行了。 程式碼:
#include<bits/stdc++.h> #define ll long long #define xx first #define yy second using namespace std; pair<ll,ll>ans; ll m,maxn,pos; inline ll calc(ll x){return x*x*x;} inline void solve(ll tot,ll tim,ll sum){ if(!tot){ans=max(ans,make_pair(tim,sum));return;} ll tmp=1; while(calc(tmp+1)<=tot)++tmp; solve(tot-calc(tmp),tim+1,sum+calc(tmp)),solve(calc(tmp)-calc(tmp-1)-1,tim+1,sum+calc(tmp-1)); } int main(){ maxn=0,pos=0; scanf("%lld",&m); solve(m,0,0); printf("%lld %lld",ans.xx,ans.yy); return 0; }