北大 算法基础-生日蛋糕POJ1190

练习代码

#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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值