其他分享
首页 > 其他分享> > 「题解」洛谷 P1731 [NOI1999]生日蛋糕

「题解」洛谷 P1731 [NOI1999]生日蛋糕

作者:互联网

瞎扯

很久之前就有学长讲过的一道题,觉得很麻烦一直没写,现在来补题了。

写完了发现好水。

题目

P1731 [NOI1999]生日蛋糕

思路

大力搜索+剪枝。

计算一下最上面的 \(m - 1\) 层最小的体积,然后就得到了一个剩余的体积 \(v\),最下面一层的半径就从 \(\sqrt{v / m}\) 开始搜。

不开 long long 会爆炸。

Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define inf 2147483647
#define int long long

int n, m, s, ans = inf;

void dfs(int step, int lastr, int lasth, int now, int q) {
    if (step > m) {
        if (now == n && ans > q) ans = q;
        return;
    }
    if (q > ans) return;
    int tot = 0, tempr = lastr - 1, temph = lasth - 1;
    for (int i = step; i <= m; ++i, --tempr, --temph) {
        tot += tempr * tempr * temph;
    }
    if (now +  tot < n) return;
    tot = 0, tempr = 1, temph = 1;
    for (int i = step; i <= m; ++i, ++tempr, ++temph) {
        tot += tempr * tempr * temph;
    }
    if (now + tot > n) return;
    for (int r = lastr - 1; r >= m - step + 1; --r) {
        for (int h = lasth - 1; h >= m - step + 1; --h) {
            if (now + r * r * h > n) continue;
            if (step == 1) dfs(step + 1, r, h, now + r * r * h, r * r + 2 * r * h);
            else dfs(step + 1, r, h, now + r * r * h, q + 2 * r * h);
        }
    }
}

signed main() {
    scanf("%d %d", &n, &m), s = n;
    for (int i = 1; i < m; ++i) {
        int v = i * i * i;
        s -= v;
    }
    dfs(1, sqrt(s / m) + 1, sqrt(s / m) + 1, 0, 0);
    if (ans == inf) puts("0");
    else std::cout << ans << '\n';
    return 0;
}

标签:now,洛谷,NOI1999,int,题解,step,体积,ans,include
来源: https://www.cnblogs.com/poi-bolg-poi/p/13790030.html