Codeforces 680D Bear and Tower of Cubes 贪心 DFS

链接

Codeforces 680D Bear and Tower of Cubes

题意

求一个不超过 \(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\n", ans, res);
	}
}

posted on 2016-06-09 10:38  张济  阅读(711)  评论(0编辑  收藏  举报

导航