• poj1190 生日蛋糕 **


    /*
    * dfs+剪枝
    * 注意到:N = (ri * ri * hi)求和
    * S = r1 * r1 + (2*ri*hi)求和 (水平面面积之和第一层的半径有关)
    *
    */

    #include
    <cstdio>
    #include
    <cmath>
    using namespace std;

    const int INF = 10000000;
    const int MAXM = 20 + 5;
    int n, m, s;

    //可以使剪枝更加精确。。 79ms->63ms
    int min_v[MAXM];
    int min_s[MAXM];

    void build(){
    min_v[m]
    = 1;
    min_s[m]
    = 1;
    for(int i=m-1; i>1; i--){ //第一层不管
    min_v[i] = min_v[i+1] + (m-i+1) * (m-i+1) * (m-i+1);
    min_s[i]
    = min_s[i+1] + 2 * (m-i+1) * (m-i+1);
    }
    }


    void dfs(int i, int left, int last_r, int last_h, int last_s){
    if(i <= m && left <= 0) return;

    if(i == m+1 && left!=0) return; //不可少

    if(i == m+1 && left==0){
    if(last_s < s){
    s
    = last_s;
    }
    return;
    }

    if((m-i+1)*(last_r-1)*(last_r-1)*(last_h-1) < left) //left太大,剪枝(不可少)
    return;
    if(i!=1 && left < min_v[i]) return; //left太小,剪枝(可略)
    if(i!=1 && last_s + min_s[i] > s) return; //可略

    //最后一层时,只要满足体积要求,则rr越大s越小,所以找到第一个后可以直接return。。
      // (可略)(由于m==1时第一层s要加上r1*r1,复杂,所以不考虑)

    if(i==m && m!=1){
    for(int rr=last_r-1; rr>0; rr--){
    if(left % (rr*rr) == 0){
    int hh = left / (rr*rr);
    if(hh < last_h && 2 * rr * hh + last_s < s){
    s
    = last_s + 2 * rr * hh; return;
    }
    }
    }
    }

    for(int rr=last_r-1; rr>m-i; rr--){
    //hh用递增,这样后面的剪枝可以直接用break而不是continue,94ms->63ms。。
    for(int hh=m-i+1; hh<last_h; hh++){
    // for(int hh=last_h-1; hh>m-i; hh--){
    if(i==1){
    if(rr * rr + 2 * rr * hh > s ) break;
    dfs(i
    +1, left-rr*rr*hh, rr, hh, last_s+2*rr*hh+rr*rr); //注意加上r1*r1
    }
    else{
    if(2 * rr * hh + last_s >= s || left-rr*rr*hh < 0) break;
    dfs(i
    +1, left-rr*rr*hh, rr, hh, last_s+2*rr*hh);
    }

    }
    }
    }


    int main(){
    scanf(
    "%d %d", &n, &m);

    build();
    s
    = INF;

    dfs(
    1, n, sqrt(n * 1.0 - m + 1) + 1, n + 2 - m, 0);

    if(s == INF)
    printf(
    "0\n");
    else
    printf(
    "%d\n", s);

    return 0;
    }
  • 相关阅读:
    Nodejs 接收RabbitMQ消息
    c#后台线程更新界面
    Nodejs JSON.parse()无法解析ObjectID和ISODate的问题
    【百度小程序】细数百度小程序踩的坑
    工作中可能用到的工具
    input输入文字的时候背景会变色,如何去掉呢?
    百度小程序开发工具不能预览
    引入外部 CDN失效时--怎么加载本地资源文件(本文以jquery为例)
    swiper插件遇到的坑
    原生JS实现JQuery的addClass和removeClass
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2106847.html
Copyright © 2020-2023  润新知