zoukankan      html  css  js  c++  java
  • 生日蛋糕

    生日蛋糕

    以下所有变量都是在正整数范围中,要制作一个体积为(npi)的蛋糕,每一层都是一个圆柱体,从上往下数,第i层蛋糕的半径为(r_i),高度(h_i),求蛋糕外表面的面积的最小值/(pi)(忽略下底面),(nleq 10000,mleq 20)

    m很小,考虑搜索,下面给出本题的结论。

    1. 搜索框架:自下而上搜索,枚举每一层蛋糕的高度和底面半径。

    2. 显然带(pi)是不好研究的,但是最终的体积和面积每一项都会有(pi),于是可以将之提出来,接下来所有式子都是已经提出了(pi)

    3. 显然非侧面积就是底下的蛋糕的上表面积,刚开始搜索时就累加即可。

    4. 考虑每一层蛋糕的高度和半径的枚举范围,设d为当前为第几层(从上往下数),前面已经确定了体积v,容易有(r_din[d,min(r_{d+1},sqrt{n-v})])((r^2hleq n-v,h_{min}=1Rightarrow rleqsqrt{n-v})),同样的道理有(h_din[d,min(h_{d+1},frac{n-v^2}{r^2}))

    5. 考虑d层内的最小体积和面积,显然当半径和高度都为1的时候达到最小,于是有最小体积(sum_{i=1}^di^3),最小面积(2sum_{i=1}^di^2),于是当已经确定的体积加上未确定的最小体积大于n那么可以return,如果已经确定的面积加上上面最小表面积大于等于最优解,return.

    6. 考虑玄学剪枝,有(2sum_{i=1}^dh_ir_i=frac{2}{r_{d+1}}sum_{i=1}^dh_ir_ir_{d+1}geq frac{2}{r_{d+1}}sum_{i=1}^dh_ir_i^2geq frac{2(n-v)}{r_{d+1}})
      于是已经确定的表面积加上最后一个式子大于等于最优解,那么return。

    参考代码:

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #define il inline
    #define ri register
    #define intmax 0x7fffffff
    using namespace std;
    int n,m,ans(intmax),r[50],h[50];
    void dfs(int,int,int);
    il int powsum(int),
    	cubesum(int);
    int main(){
    	scanf("%d%d",&n,&m);
    	h[m+1]=r[m+1]=intmax,dfs(m,0,0);
    	printf("%d",ans);
    	return 0;
    }
    il int cubesum(int n){
    	return pow(n*(n+1)/2,2);
    }
    il int powsum(int n){
    	return n*(n+1)*(2*n+1)/6;
    }
    void dfs(int d,int v,int s){
    	if(v+cubesum(d)>n)return;
    	if(s+powsum(d)*2>=ans)return;
    	if(s+2*(n-v)/r[d+1]>=ans)return;
    	if(!d){if(v==n)ans=s;return;}
    	int rr(min(r[d+1]-1,(int)sqrt(n-v)));
    	for(int i(rr),j;i>=d;--i)
    		for(j=min(h[d+1]-1,(n-v)/(i*i));j>=d;--j)
    			r[d]=i,h[d]=j,dfs(d-1,v+i*i*j,s+2*i*j+(d==m)*i*i);
    }
    
    
  • 相关阅读:
    Git
    Git
    Git
    Git
    Docker
    Linux
    Linux
    Python
    Python
    SQL
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/11276451.html
Copyright © 2011-2022 走看看