uestc oj 1670 积木
来源:互联网 发布:淘宝开店怎么刷销量 编辑:程序博客网 时间:2024/04/29 10:23
积木
本题采用深度优先搜索+剪枝可以完成。
由于本题只有20层的数据量不是很大,可以选用DFS遍历所有满足条件(下面的圆柱体的底面半径和高度都必须比上面的大)
的组合,分别并分别求出面积进行比较就行了,最后求出涂色面积最小的量。
void dfs(int m_left, int n_left,int r_last,int h_last,int now_s)
分别代表着还剩下的层数,还剩下的体积,上一层的半径,上一层的高度,现在的表面积。
剪枝 :如果剩下层数的最小体积仍然大于剩下的体积 return
如果现在的面积加上剩下的部分的最小面积仍然大于现在的假定最优解,则直接return
在求取剩下层数的最小体积的时候,假定最上面第一层半径为1,高度为1,则紧接着下一层是半径2,高度2,一次递推
则得出体积为i*i*i(pai)
在计算面积的时候要注意的就是凡是侧面积之外的面积和其实等于最下面那个圆柱体的底面积,这个很好说明的。
然后的话在计算面积的时候只用在增加一个圆柱体的时候初始化底面积再加上侧面积就行了。
在求取剩下层数最小面积的时候要注意其实就是现在的面积加上剩下的体积*2/r_last 这个很好利用几何证明的。
还有就是在每一次递归的时候注意求取上下界的问题。
半径的范围自然是上一层的半径-1到剩下的层数 一个是上边界一个是下边界
高度的范围自然是在这一层的最大体积/这一层的底面积 几何可以很容易求出
数学几何知识很重要哈在这样的题目当中。
本题采用深度优先搜索+剪枝可以完成。
由于本题只有20层的数据量不是很大,可以选用DFS遍历所有满足条件(下面的圆柱体的底面半径和高度都必须比上面的大)
的组合,分别并分别求出面积进行比较就行了,最后求出涂色面积最小的量。
void dfs(int m_left, int n_left,int r_last,int h_last,int now_s)
分别代表着还剩下的层数,还剩下的体积,上一层的半径,上一层的高度,现在的表面积。
剪枝 :如果剩下层数的最小体积仍然大于剩下的体积 return
如果现在的面积加上剩下的部分的最小面积仍然大于现在的假定最优解,则直接return
在求取剩下层数的最小体积的时候,假定最上面第一层半径为1,高度为1,则紧接着下一层是半径2,高度2,一次递推
则得出体积为i*i*i(pai)
在计算面积的时候要注意的就是凡是侧面积之外的面积和其实等于最下面那个圆柱体的底面积,这个很好说明的。
然后的话在计算面积的时候只用在增加一个圆柱体的时候初始化底面积再加上侧面积就行了。
在求取剩下层数最小面积的时候要注意其实就是现在的面积加上剩下的体积*2/r_last 这个很好利用几何证明的。
还有就是在每一次递归的时候注意求取上下界的问题。
半径的范围自然是上一层的半径-1到剩下的层数 一个是上边界一个是下边界
高度的范围自然是在这一层的最大体积/这一层的底面积 几何可以很容易求出
数学几何知识很重要哈在这样的题目当中。
#include<cstdio>#include<cstring>#define MAX 10000int n,m,res;inline int cal(int floor){ int i = 0, res = 0; for(i=1;i<=floor;i++) res +=i*i*i; return res;}inline int minvol(int floor){ return cal(floor);}void dfs(int m_left, int n_left,int r_last,int h_last,int now_s){ if(n_left<minvol(m_left)) return ; if(now_s+2*n_left/r_last>res) return; if(m_left == 0) { if(n_left==0&&res>now_s) res = now_s; return; } for(int i=r_last-1;i>=m_left;i--) { if(m_left==m) now_s = i*i; int maxh = h_last-1; if(maxh>(n_left-minvol(m_left -1))/i/i) maxh=(n_left-minvol(m_left -1))/i/i; for(int j=maxh;j>=m_left;j--) dfs(m_left - 1,n_left-i*i*j,i,j,now_s+2*i*j); }}int main(){ //freopen("1.txt","r",stdin); while(scanf("%d%d",&n,&m)==2) { res = MAX; dfs(m,n,100,10000,0); if(res == MAX) res = 0 ; printf("%d\n",res); }}
- uestc oj 1670 积木
- uestc oj 1793 Kalindrome
- uestc oj 1227 Hotel
- uestc oj 1500 AreYouBusy
- uestc oj 1484 STAMPS
- uestc oj 1272 Sticks
- uestc oj 1230 Picture
- uestc oj 1223 Islands
- uestc oj 1001 DotNotation
- 吐槽 uestc oj
- uestc oj 1876 聚会
- UESTC OJ 1830
- UESTC OJ Windy 数
- uestc oj 1796 Flash Mob
- uestc oj 1221 Sliding Window
- uestc oj 1868 Condorcet Winners
- uestc oj 1690 最少花费
- uestc oj 1668 分数拆分
- Android倚天剑之Notification之亮剑IOS
- 扑克牌24点游戏JAVA实现
- uestc oj 1272 Sticks
- uestc oj 1488 Flip Game
- struts2文件下载出现Can not find a java.io.InputStream with the name [imageStream] in the invocation stack.
- uestc oj 1670 积木
- java 对一单词的找出全部组合
- uestc oj 1230 Picture
- 表格布局(TableLayout)的简单使用
- Codeforces Round #187 (Div. 2) 只水果两题。。。
- POJ 1177 Picture (线段树+离散化+扫描线) 详解
- 黑马程序员--第十八天:IO流第一天
- 线段树(segment tree)
- 黑马程序员—java基础之反射与正则表达式