zoukankan      html  css  js  c++  java
  • 洛谷 P1731 [NOI1999]生日蛋糕 题解

    每日一题 day53 打卡

    Analysis

    观察一个蛋糕的俯视图,上表面的面积其实就是最下面那一层的底面积,所以在第一次搜索的时候加入这个底面积,之后就只用考虑侧面积就好啦.

    就是每次枚举r和h,如何选取上下界呢?

    将上一层的高度记作lh,上一层的半径记作lr,则上界很好判断,就是lh−1和lr1

    底层应该是选取三次根号下20000约为28的范围

    现在考虑下界:

    自然选取1是会T得很惨的,下界就是最小值嘛,最上面一层的r和h的最小值都是1啊,那还有几层下界就是几啦!

    然后来愉快地剪枝:

    比较好想的剪枝是这两个:

    1. 当当前的面积总和已经超过之前的答案时,return

    2. 当当前体积超过了要求的体积时,return

    还有一些剪枝,思维难度也不算高:

    • 当现在的已有体积加上之后的最大(并不是真正的最大,会比最大还要大一些)体还要小于要求的体积时,return

    • 当当前的已有面积加上之后的最小(自然也是比真正的最小还要小一些)面积比已有答案还要大时,return

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define int long long
     6 #define INF 2147483647
     7 #define rep(i,s,e) for(register int i=s;i<=e;++i)
     8 #define dwn(i,s,e) for(register int i=s;i>=e;--i)
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0,f=1;
    13     char c=getchar();
    14     while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
    15     while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
    16     return f*x;
    17 }
    18 inline void write(int x)
    19 {
    20     if(x<0) {putchar('-'); x=-x;}
    21     if(x>9) write(x/10);
    22     putchar(x%10+'0');
    23 }
    24 int n,m,ans=INF;
    25 void dfs(int layer,int volume,int area,int radius,int height)
    26 {
    27     if(area>=ans) return;
    28     if(layer==m+1&&volume==n)
    29     {
    30         ans=min(ans,area);
    31         return;
    32     }
    33     if(volume>=n) return;
    34     int now_layer=m-layer+1;
    35     if(volume+now_layer*radius*radius*height<n) return;
    36     if(area+now_layer*2>ans) return;
    37     if(layer==1)
    38     {
    39         rep(r,m,radius)
    40             rep(h,m,height)
    41                 dfs(layer+1,volume+r*r*h,area+2*r*h+r*r,r,h);
    42     }
    43     else 
    44     {
    45         rep(r,now_layer,radius-1)
    46             rep(h,now_layer,height-1)
    47                 dfs(layer+1,volume+r*r*h,area+2*r*h,r,h);
    48     }
    49 }
    50 signed main()
    51 {
    52     n=read();m=read();
    53     dfs(1,0,0,28,28);
    54     if(ans==INF) write(0);
    55     else write(ans);
    56     return 0;
    57 }

    请各位大佬斧正(反正我不认识斧正是什么意思)

  • 相关阅读:
    学习Py——自己模拟写的一个Range功能
    心情随笔20180529
    记一次排查局网内的ARP包 “不存在的” MAC 地址及 “不存在的”IP 所发的ARP包
    最长反链
    浅谈矩阵树定理
    毒瘤dp 学校食堂
    P3565 由简单的树形dp 引入 长链刨分
    noi 2017 整数
    记人生的抉择
    2019 HL SC day10
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/11972192.html
Copyright © 2011-2022 走看看