题目
自己没看题解写的,摸石头过河,解释一下
首先,输入输出都是正整数。先搞定输入,再判断条件,如果无解,输出0,否则输出蛋糕外表面面积Q(这里用全局变量,开long long)。
然后写dfs函数,函数形参先写了一个layer, r, h。这些数据是需要递归时传入的,在每一次的搜索中,r,h都会变。
先写结束条件,搜索层数layer与输入层数m相同时,return结束。后来写着写着又在形参加了两个变量,一个是奶油面积total_CreamArea(蛋糕外表面面积),一个是搜索中的总体积。结束条件中另外再加一个判断就是当总体积totalvolume = n时,取Q和奶油面积total_CreamArea的最小值来更新Q的值
写到这里就有问题了,遇到瓶颈。这个r,h的范围是多少呢?
#include <bits/stdc++.h>
using namespace std;
int n, m; //蛋糕体积,层数
long long Q = 9e10;
void dfs(int layer, int r, int h,int total_CreamArea, int totalvolume)
{
if(layer == m) //层数 = 输入层数
{
if(totalvolume == n)
Q = min(Q, total_CreamArea);
return; //结束dfs
}
//for(int i = r; i>=0; i--)
int newArea = total_CreamArea + 2*r*h; //加上侧面积,底面积就是第一层的大圆面积
int newVolume = totalvolume + r*r*h; //加上新一层的体积
dfs(layer+1, r, h, newArea, newVolume);
}
int main()
{
cin>>n>>m;
dfs(1, )
if(Q == 9e10)
cout << 0 << endl;
else
cout << minvolume << endl;
}
后来看了视频,还有罗老师的博客,才知道原来是这样确定r, h的范围的。当然剪枝也是不能少的,没有剪枝就会超时。
我是推不出来这个条件:2(n−v)/r+s≥ans,测试过没有这个条件也有70分!
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/weixin_43914593/article/details/135489983
【AC参考代码】
#include <bits/stdc++.h>
using namespace std;
int n, m; //蛋糕体积,层数
int Q = 9e8;
int minVolume[16], minArea[16]; //用于剪枝
void dfs(int layer, int r, int h,int total_CreamArea, int totalvolume)
{
if(layer == 0) //层数 = 输入层数
{
if(totalvolume == n)
Q = min(Q, total_CreamArea);
return; //结束dfs
}
if(minVolume[layer] + totalvolume > n || totalvolume > n) //体积大于输入值
return;
if(total_CreamArea + minArea[layer] >= Q) //面积比最小面积还要大,舍去
return;
if(2*(n - totalvolume)/r + total_CreamArea >= Q) //2(n−v)/r+s≥ans
return;
for(int newR = min(r-1, (int)(sqrt(n-totalvolume)) ); newR >= layer; newR--)
{
if(layer == m) //上表面积,从上往下看就是一个圆
total_CreamArea = newR * newR;
//体积公式求h
for(int newH = min(h-1, (n-totalvolume)/(newR * newR) ); newH >= layer; newH--)
{
int newArea = total_CreamArea + 2*newR*newH; //加上侧面积,底面积就是第一层的大圆面积
int newVolume = totalvolume + newR*newR*newH; //加上新一层的体积
dfs(layer-1, newR, newH, newArea, newVolume);
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
minVolume[i] = minVolume[i-1] + i*i*i; //R^3
minArea[i] = minArea[i-1] + 2*i*i; //2*R^2
}
dfs(m, 9e8, 9e8, 0, 0);
if(Q == 9e8)
cout << 0 << endl;
else
cout << Q << endl;
}
看视频吧,视频肯定比我讲得清楚。视频链接:【B24 DFS剪枝 生日蛋糕】