描述

​「luogu P1731」​

题解

一道DFS。

初始思路: 枚举当前层的高度和半径,然后递归

预计得分:\(20pts\)

爆搜会超时,于是我们想到剪枝。

剪枝1: 当前抹奶油的表面积已经大于最优解。

剪枝2: 当前的体积加上后面最大的体积仍然小于蛋糕体积。

剪枝3: 当前抹奶油的表面积加上后面最小的表面积仍然小于最优解。

预计得分:\(70pts\)

考虑贪心,高度和半径优先从大的开始选,这样可以通过前面的剪枝节省很多时间

\(code\)

#include <bits/stdc++.h>
using namespace std;
int n, m;
int r[25], h[25];
int ans = INT_MAX;
void dfs(int t, int s, int sum) {
if (s > n || sum > ans || s + (r[t - 1] * r[t - 1] * h[t - 1]) * (m - t + 1) < n || sum + (m - t + 1) > ans) return;
// cout << t << ' ' << s << ' ' << sum << endl;
if (t == m + 1 && s == n) {
ans = min(ans, sum);
return;
}
if (t > m) return;
for (int i = r[t - 1] - 1; i >= m - t + 1; i--) {
for (int j = h[t - 1] - 1; j >= m - t + 1; j--) {
r[t] = i, h[t] = j;
if (t != 1) dfs(t + 1, s + i * i * j, sum + 2 * i * j);
else dfs(t + 1, s + i * i * j, sum + 2 * i * j + i * i);
r[t] = 0, h[t] = 0;
}
}
}
signed main() {
scanf("%d %d", &n, &m);
r[0] = (int)sqrt(n), h[0] = (int)sqrt(n);
dfs(1, 0, 0);
if (ans == INT_MAX) printf("0");
else printf("%d", ans);
return 0;
}