洛谷 P1731 [NOI1999]生日蛋糕 题解

主要思路:

这道题刚拿到就知道要用dfs,但是dfs肯定会T,所以我们要用剪枝来优化搜索的方案数量。

1 要是剩下体积除以最大(虽然取不到)半径所得到的表面积+累计表面积大于答案退出

2 要是剩下来的体积已经小于该层最小体积了就退出

3 还有为了剪枝,我们要起先预处理某一层的最大不可的表面积和体积

4 要是最小面积+当前累计表面积已经比已知答案大了就退出

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define INF 2147483647 
 7 using namespace std;
 8 int a[201],b[201],m,n,ans;//a存储表面积,b存储体积
 9 void dfs(int v,int s,int p,int r,int h) { //v为已用体积,s为已有表面积,p为剩余层数,r为半径,h为高
10     int i,j,yy;
11     if(p==0) { //如果已经搜到了顶层
12         if (v==n&&s<ans)//判断是否符合要求并得到更优解
13             ans=s;
14         return ;
15     }
16     //各种剪枝
17     if(v+b[p-1]>n) return ;//体积超出
18     if(s+a[p-1]>ans) return ;//表面积超出
19     if(2*(n-v)/r+s>=ans)  return; //当前的表面积+余下的侧面积>当前最优值 
20     for(i=r-1; i>=p; i--) { //枚举半径
21         if(p==m) s=i*i;
22         yy=min((n-v-b[p-1])/(i*i),h-1);
23         for(j=yy; j>=p; j--) //枚举高
24             dfs(v+i*i*j,s+2*i*j,p-1,i,j);
25     }
26 }
27 int main() {
28     cin>>n>>m;
29     ans=INF;//用于输出
30     a[0]=b[0]=0;
31     for(int i=1; i<21; i++) {
32         a[i]=a[i-1]+2*i*i;//第i层使用的最大表面积
33         b[i]=b[i-1]+i*i*i;//第i层使用的最大体积
34     }
35     dfs(0,0,m,n+1,n+1);
36     if(ans==INF) cout<<0;
37     else cout<<ans;
38     return 0;
39 }
请各位大佬斧正(反正我不认识斧正是什么意思)

 

转载于:https://www.cnblogs.com/handsome-zyc/p/11237378.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值