• 洛谷 P1731 [NOI1999]生日蛋糕 && POJ 1190 生日蛋糕


    题目传送门(洛谷)  OR 题目传送门(POJ)

    解题思路:

    一道搜索题,暴力思路比较容易想出来,但是这道题不剪枝肯定会TLE.所以这道题难点在于如何剪枝.

    1.如果当前状态答案已经比我们以前某个状态求出来的答案还要大,那么我们就没有必要搜下去,直接return.

    2.如果有某个状态,在这之后假设所有答案都是最优,还比我们当前已经求出来的最小值大,那么哇哦们也没有必要搜下去,return;

    3.如果在某个状态之后,所有层蛋糕都用最大体积,也无法达到答案体积,那么也没必要搜,return.

    以上三条剪枝对于这道题来说已经够了.

    如果还想再优化一下,那么可以求出每层蛋糕当前R和H范围,在范围之间枚举,这样做也会使程序快一点,对于这道题来说,没必要//就因为写这个剪枝花了我1个半小时,最后还没写对,直接去掉这条剪枝,AC.

    AC代码:

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<math.h> 
     5 
     6 using namespace std;
     7 
     8 int n,m,ans = 0x7f7f7f7f,_min[25],oo[25];
     9 
    10 int find_max(int nn,int h,int r) {
    11     int vv = 0;
    12     for(int i = 1;i <= m - nn + 1; i++) 
    13         vv += (h - i) * (r - i) * (r - i);
    14     return vv;
    15 }
    16 
    17 inline void dfs(int deep,int h,int r,int v,int len) {
    18     if(deep == m + 1) {
    19         if(v != 0) return ;
    20         ans = min(ans,len);
    21         return ;
    22     }
    23     if(v < 0) return ;
    24     int u = len;
    25     u += _min[deep];
    26     if(ans < u) return ;
    27     u = find_max(deep,h,r);
    28     if(v > u && deep != 1) return;
    29     for(int i = 1;i < r; i++) {
    30         for(int j = 1;j < h; j++) {
    31             if(i * i * j > v) continue;
    32             if(a[deep][i][j]) continue;
    33             if(deep == 1) len = i * i;
    34             dfs(deep + 1,j,i,v - j * i * i,len + 2 * j * i);
    35         }
    36     }
    37 }
    38 
    39 inline void special() {
    40     for(int i = 1;i <= sqrt(n); i++) {
    41         if(n % (i * i) != 0) continue;
    42         int j = n / (i * i);
    43         int len = i * i + i * 2 * j;
    44         ans = min(ans,len);
    45     }
    46 }
    47 
    48 int main()
    49 {
    50     scanf("%d%d",&n,&m);
    51     for(int p = m;p >= 1; p--) 
    52         _min[p] = _min[p+1] + (m - p + 1) * 2 * (m - p + 1);
    53     if(m == 1) special();
    54     else dfs(1,25,25,n,0);
    55     if(ans == 0x7f7f7f7f) printf("0");
    56     else printf("%d",ans);
    57     return 0;
    58 }
  • 相关阅读:
    一些业内有名的网站收集
    WCF重载
    FCKEditor fckconfig.js配置,添加字体和大小 附:中文字体乱码问题解决
    查询第几条到第几条的数据的SQL语句
    SPOJ 9939 Eliminate the Conflict
    UVA 10534 Wavio Sequence
    HDU 3474 Necklace
    POJ 2823 Sliding Window
    UVA 437 The Tower of Babylon
    UVA 825 Walking on the Safe Side
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/11494862.html
Copyright © 2020-2023  润新知