练习代码
#include<iostream>
#include<vector>
using namespace std;
int N, M;
int minArea;//面积最优解
int minV[30];//n层最小体积
int minA[30];//n层最小面积
int area=0;//当前n层的侧面积+顶的面积
int MaxVForNRH(int n, int r, int h) {//n层半径r高h的最大体积
int V=0;
for (int i = 0; i < n; i++)
V += (r-i) *( r-i) * (h-i);
return V;
}
void Dfs(int v, int n, int r, int h) {
if (n == 0)
if (v == 0) {
minArea = min(minArea, area);
return; }//计算出了结果
else
return;//无解退出
if (area >= minArea) return;//当前两种大于最优解
if (r < n || h < n) return;//小层数,不可能完成
if (minV[n] > v) return;//往上最小体积也大于V
if (area + minA[n] >= minArea) return;//n层最小面积也比最优解大
if (MaxVForNRH(n, r, h) < v) return;//n层最大体积也比v小,无解
for (int rr = r; rr >= n; rr--)//枚举r h
{
if (n == M)
area = rr * rr;//第一层时执行
for (int hh = h; hh >= n; hh--) {
area += 2 * rr * hh;//加上这层的侧面积
Dfs(v - rr * rr * hh, n - 1, rr - 1, hh - 1);
area -= 2 * rr * hh;
}
}
return;
}
int main() {
cout << "输入体积和层数:";
cin >> N >> M;
minV[0] = 0;
minA[0] = 0;
minArea = 1 << 30;
for (int i = 1; i <= M; i++)
{
minV[i] += minV[i - 1] + i * i * i;
minA[i] += minA[i - 1] + 2 * i * i;
}
if (minV[M] > N)
cout << "无解!" << endl;
else {
int MaxR = sqrt(double((N - minV[M - 1]) / M)) + 1;//最大半径
int MaxH = (N - minV[M - 1]) / (M * M) + 1;//最大高度
Dfs(N, M, MaxR, MaxH);
if (minArea == 1 << 30)
cout << "没有找到最小表面积." << endl;
else
cout << minArea << endl;
}
return 0;
}
例:
输入:129 3
输出:87