codeforces基础题——#356(div2) D

来源:互联网 发布:温州淘宝店主猝死 编辑:程序博客网 时间:2024/05/16 11:25

#356(div2) D

题目大意: 你有一些边长为正整数的立方体,边长为i的立方体体积为i * i * i, 现在有人要用这些正方体搭塔, 每种边长的正方体都有无限多个, 如果现在给定体积正方体的总体积k, 那么它会采用一种贪心的方法, 每次选用可选的体积中最大的来搭塔,问所有正方体体积和小于m(1 <= m<= 1e15)是最多有多少个正法体组成, 如果有多组解则输出体积最大的举个例子, 当m = 48, 数量最多的方案为42, 2342 = 27 * 1 + 8 * 1 + 1 * 7, 数量为 923 = 8 * 2 + 1 * 7, 数量为 9所以答案为42

题解:
首先我们知道, 当上限越高, 答案也只会越高, 因为有更多选择。
假设当前能选用的最大正方体边长为f, 那么最优情况中最大的正方体要么是f, 要么是f - 1, 因为如果选f - 1, 那么剩下的体积总和上限为f3 - (f - 1) 3,否则就会优先选用f, 同样, 如果选了f - 2,则剩下的体积上限为(f - 1)3 - (f - 2) 3
我们发现f3 - (f - 1) 3 > (f - 1)3 - (f - 2) 3,
即选f - 1的情况必定优于选f - 2的情况
所以我们可以dfs, 枚举选f - 1, 和f为最大正方体即可。

#include <cstdio>#include <iostream>using namespace std;typedef long long LL;LL q(LL x) {return x * x * x;}pair<LL, LL> ans;void dfs(LL lim, LL num, LL sum){    //printf("%d %d %d\n", lim, num, sum);    if (lim <= 0){        ans = max(ans, make_pair(num, sum));        return ;    }    LL t = 1;    while(q(t + 1) <= lim) t ++;    dfs(lim - q(t), num + 1, sum + q(t));    if (t > 1) dfs(q(t) - 1 - q(t - 1), num + 1, sum + q(t - 1));}int main(){    LL m;    scanf("%I64d", &m);    dfs(m, 0, 0);    printf("%I64d %I64d\n", ans.first, ans.second);    return 0;}
0 0
原创粉丝点击