题解
从蛋糕从下往上搜索,上表面积就是最下面圆的面积,求解过程注重侧面积和体积即可,
假设当前状态有 s,v,rdep+1∼m,hdep+1∼m, dep 对应的状态,有:
n−v≥r2dephdep
有上界:
rdep=min(n−v,rdep+1−1)
hdep=min(n−vr2dep,hdep+1−1)
有下界:
rdep=dep,hdep=dep
很明显,ri=i,hi=i 是最小的情况,
它们对应的 minsi=2rihi=2i2,minvi=r2ihi=i3
如果当前结果加最小情况超过答案,那么后面就不会有解。
在有解的情况下,有下面不等式成立:
s1∼dep−1=2dep−1∑i=1rihi,v1∼dep−1=n−v=dep−1∑i=1r2ihi
ri<rdep,1≤i≤dep−1
s1∼dep−1=2dep−1∑i=1rihi=2rdepdep−1∑i=1rihirdep≥2rdepdep−1∑i=1r2ihi
s1∼dep−1≥2(n−v)rdep
即,2(n−v)rdep 是后面未求面积的下限,如果 2(n−v)rdep+s 大于答案,那么这样的状态是不会更优的。
# include <iostream>
# include <cmath>
using namespace std;
const int MAXN = 20 + 5, INF = 1E9;
int n, m, min_s[MAXN], min_v[MAXN], ans = INF, r[MAXN], h[MAXN];
void DFS(int dep, int s, int v)
{
if(dep == 0)
{
if(v == n) ans = min(ans, s);
return;
}
r[dep] = min((int)(double)sqrt(n - v), r[dep + 1] - 1);
while(dep <= r[dep])
{
h[dep] = min((int)(double)(n - v) / (r[dep] * r[dep]), h[dep + 1] - 1) + 1;
while(dep < h[dep])
{
h[dep]--;
if(ans < s + min_s[dep] || n < v + min_v[dep]) continue;
if(ans < s + (double)2 * (n - v) / r[dep]) continue;
if(dep == m) s = r[dep] * r[dep];
DFS(dep - 1, s + 2 * r[dep] * h[dep], v + r[dep] * r[dep] * h[dep]);
if(dep == m) s = 0;
}
r[dep]--;
}
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= m; i++)
{
min_s[i] = min_s[i - 1] + 2 * i * i;
min_v[i] = min_v[i - 1] + i * i * i;
}
r[m + 1] = h[m + 1] = INF;
DFS(m, 0, 0);
if(ans == INF) cout << 0 << endl;
else cout << ans << endl;
return 0;
}
hao