【2018/09/23】T2
阿新 • • 發佈:2018-12-11
塔(30/100)
描述
小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
【分析】
這個題目描述依舊很鬼畜……大部分同學又沒有讀懂了(主要是題意沒有敘述清楚)
重述:
給定m,請你確定[ 1 , m ]中的 x ,使得用到的積木數最多,每次取積木的原則:取當前可取的最大的那一個。在滿足積木數最大的情況下,輸出最大的 x
這下應該清楚一些了吧。
首先30分的暴力:列舉 x (1~m) ,然後挨個判斷
50分:dp
100分:在50 分的dp上進行優化
找到最大的 a 使得 a^3 不超過 m,接下來 X 的第一塊積木必然為 a 或 a-1 1.用 a,m2=m-a^3 2.用 a-1, X最大為 a^3-1, m2 = a^3-1-(a-1)^3=3*(a^2-a) 3.用 a-2, X最大為(a-1)^3-1,m2 ’ =(a-1)^3-1-(a-2)^3=3*a^2-9a+6 顯然2一定比3優
【程式碼】
#include<bits/stdc++.h> #define ll long long using namespace std; ll m; pair<ll,ll> ans; ll val[1000009],num=0; void search(ll x,ll steps,ll ss){ if(x==0){ ans=max(ans,make_pair(steps,ss)); return ; } ll a=lower_bound(val+1,val+100001,x)-val; if(val[a]>x) a--; search(x-val[a],steps+1,ss+val[a]); if(a-1>=0) search(val[a]-1-val[a-1],steps+1,ss+val[a-1]); } int main(){ scanf("%lld",&m); for(int i=1;i<=100000;++i) val[i]=1ll*i*i*i; search(m,0,0); printf("%lld %lld",ans.first,ans.second); return 0; }