【CodeForces】679 B. Bear and Tower of Cubes
【题目】B. Bear and Tower of Cubes
【题意】有若干积木体积为1^3,2^3,...k^3,对于一个总体积X要求每次贪心地取<=X的最大积木拼上去(每个只能取一次)最后总体积恰好为X,求给定的1~m内使积木数量最大的X,相同取X较大者。m<=10^15。
【题解】对于一个给定的限制m,考虑最大那块积木的选择,设最大的<=m的积木是a^3。
1.取a^3,那么下次限制为m-a^3。
2.取(a-1)^3,那么下次限制为a^3-1-(a-1)^3。
3.取(a-2)^3,那么下次限制为(a-1)^3-1-(a-2)^3。
显然取(a-2)不如取(a-1)优,所以对于给定的限制m只需要考虑取a^3或(a-1)^3,然后对新的限制递归进行。
复杂度O(n^1/3)。
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; ll ansp=0,ans=0,m; ll p(int x){return 1ll*x*x*x;} void dfs(ll m,ll x,ll y){ if(m<=0){if(x>ansp||(x==ansp&&y>ans))ansp=x,ans=y;return;} int t=0; while(p(t+1)<=m)t++; dfs(m-p(t),x+1,y+p(t)); if(t>1)dfs(p(t)-1-p(t-1),x+1,y+p(t-1)); } int main(){ scanf("%lld",&m); dfs(m,0,0); printf("%lld %lld",ansp,ans); return 0; }
自己的写法:通过尽量堆积小数字可以得到最大数量,然后从大到小将每个数尽量增大(通过全部扫描判断每个数字是否增大,n很小)。