链接
题意
求一个不超过 (m) 的最大体积 (X), 每次选一个最大的 (x) 使得 (x^3) 不超过当前剩余体积。问在能选最多个数的情况下,(X) 最大是多少
思路
对于每一次选择,首先要保证选完后的剩余体积最大,这样就保证了能选最多个数。然后在这基础上保证 (X) 最大。
考虑对于最大的 (a),使得 (a^3<=m).
如果当前选择的是 (a),则剩余体积就是 (m1 = m - a^3)
如果当前选择的是 (a - 1), 则剩余体积就是 (m2 = (a^3 - 1) - (a - 1)^3). 要保证 (a-1) 是可选的最大的,对 (m) 的上限有要求
如果当前选择的是 (a - 2), 则剩余体积就是 (m3 = (a-1)^3 - 1 - (a - 2)^3).
所以可以发现在 (a>=1) 的情况下, (m2) 恒不小于 (m3), 所以就不用考虑 (a-2) 了
这样对于每一个状态,只要考虑 (a) 和 (a - 1). 时间复杂度是 (O(m^frac{1}{3}))
代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <string>
#define LL long long
#define INF 0x3f3f3f3f
#define eps 1e-8
#define TRI_POW(x) (x) * (x) * (x)
using namespace std;
LL ans, res;
void work(LL left, LL cnt, LL cur){
if (left == 0){
if (cnt > ans){
ans = cnt;
res = cur;
}
return;
}
LL x = 1;
while (TRI_POW(x + 1) <= left){
++x;
}
work(left - TRI_POW(x), cnt + 1, cur + TRI_POW(x));
if (x > 0){
work(TRI_POW(x) - 1 - (TRI_POW(x - 1)), cnt + 1, cur + TRI_POW(x - 1));
}
}
int main(){
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
LL n;
while (~scanf("%I64d", &n)){
ans = 0;
work(n, 0, 0);
printf("%I64d %I64d
", ans, res);
}
}