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

    中文题

    题目分析

    搜索题,非常好的剪枝

    由于深度一定(m),所以使用深度优先搜索,自上而下的设定蛋糕序号,最顶层的为第1层,……,最底层的蛋糕为第m层,很明显满足题目条件的前i层的(从顶层(也就是编号为1的层)开始计数)最小面积mins[i]和体积minv[i]是在该层的半径以及高度都为i时取得,如果采用一般的神搜肯定会超时,所以这题还需要剪枝,剪枝条件有(从m层向上搜,假设前dep层的体积为sumv,面积为sums,当前所得的最小面积为best):
      1. 因为前dep层的体积为v,如果剩下的几层的体积都取最小可能值,总体积还是比n大,那么则说明前dep层的方案不可行,所以可以剪枝(剪枝条件为:v+minv[dep-1]>n)
      2. 因为前dep层的面积为s,如果剩下的几层的面积都取最小可能值,所得的面积和比已经得到的所求的最小面积best大,也可以进行剪枝(剪枝条件为:s+mins[dep-1]>ans)
      3. 因为前dep层的体积为v,那么剩余的m-dep层的体积满足:n-sumv=(h[k]*(r[k]^2)+……+h[m]*(r[m]^2))      (k=dep+1,……,m)
         而剩余部分的表面积满足:lefts=2*(r[k]*h[k]+……+r[m]*h[m])>2*(n-v)/r[dep]                    (k=dep+1,……,m)
         显然有上述不等式lefts=ans-s>2*(n-v)/r,即2*(n-v)/r+s<ans,所以当2*(n-v)/r[i]+s>=anst时也可以进行剪枝.

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #define INF 1000000000
    using namespace std;
    int n,m,minv[30],mins[30],ans;
    void dfs(int v,int dep,int s,int r,int h)
    {

    if(dep==0)
    {
    if(v==n)
    ans=min(ans,s);
    return ;
    }
    if(v+minv[dep-1]>n||s+mins[dep-1]>ans||(2*(n-v)/r+s>=ans))
    return ;
    for(int rr=r-1; rr>=dep; rr--)
    {
    for(int hh=min(h-1,(n-v-minv[dep-1])/rr/rr); hh>=dep; hh--)
    {
    if(dep==m)
    s=rr*rr;
    dfs(v+rr*rr*hh,dep-1,s+2*rr*hh,rr,hh);
    }
    }
    }
    int main()
    {
    minv[0]=0;
    mins[0]=0;
    for(int i=1;i<=20;i++)
    {
    minv[i]=minv[i-1]+i*i*i;
    mins[i]=mins[i-1]+2*i*i;
    }
    while(scanf("%d %d",&n,&m)!=EOF)
    {
    ans=INF;
    dfs(0,m,0,n+1,n+1);
    if(ans==INF)
    printf("0 ");
    else
    printf("%d ",ans);
    }

    return 0;
    }

  • 相关阅读:
    批处理学习总结之常用命令1
    Delphi常用数据类型
    Delphi预编译指令总结
    Delphi同步互斥总结
    MyEclipse 环境配置总结
    倒排索引
    laravel 学习相关笔记
    elasticsearch倒排索引原理
    原生sql和 TP sql怎么关联?
    elastic
  • 原文地址:https://www.cnblogs.com/tsw123/p/4361044.html
Copyright © 2011-2022 走看看