洛谷 1731 生日蛋糕 dfs+剪枝

来源:互联网 发布:电脑绘画卡通人物软件 编辑:程序博客网 时间:2024/05/23 00:41

题目:

https://www.luogu.org/problem/show?pid=1731

加了四个剪枝;

明确枚举的对象——每层的高度和半径;
∑表面积=∑圆柱侧面积+最大的底面积;(画图);

总结:
注意细节;

#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>using namespace std;int V,n,ans=1<<23;int minV[1001],minA[1001];int calc(int tot,int r,int h){//每一层都为最大体积的情况,    int v=0;    for(int i=0;i<tot;i++)//h,r每次只减1;        v+=(r-i)*(r-i)*(h-i);    return v;}void dfs(int v,int tot,int r,int h,int s){    if(tot==0)    {        if(v) return;        ans=min(s,ans);        return;    }    if(v<=0) return;    if(s+minA[tot]>=ans) return;//前面的面积+当前最小面积>答案    if(minV[tot]>v) return;//剩余体积<当前最小体积都无法更新;    if(calc(tot,r,h)<v) return;//剩余层数"用最大的体积"仍小于剩余体积    if(r<tot || h<tot) return;//r,h至少等于层数;    for(int i=r;i>=tot;i--)//半径;    {        if(tot==n) s=i*i;        for(int j=h;j>=tot;j--)//高度;            dfs(v-i*i*j,tot-1,i-1,j-1,s+2*i*j);    }    return;}void solve(){    scanf("%d%d",&V,&n);    for(int i=1;i<=n;i++)//预处理每层最小体积与面积.方便剪枝;        minV[i]=minV[i-1]+i*i*i,minA[i]=minA[i-1]+2*i*i;    if(minV[n]>V) {cout<<0<<endl;return;}//  cout<<minV[n]<<endl;    int maxH=(V-minV[n-1])/(n*n)+1;//V-minV[n-1]为最大体积,n为最小半径;    int maxR=sqrt((double)(V-minV[n-1])/n)+1;//同理;    dfs(V,n,maxR,maxH,0);    if(ans== 1<<23 ) cout<<"0";    else cout<<ans;}int main(){    solve();    return 0;}
阅读全文
1 0
原创粉丝点击