zoukankan      html  css  js  c++  java
  • 洛谷 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 }
  • 相关阅读:
    安装maven报错及解决
    Servlet包导入
    理解SQL SERVER的逻辑读,预读和物理读以及索引
    第六章(函数)编程题二
    第六章(函数)编程题一
    第五章(使用对象) 编程题一
    第三章(循环) 编程题 4
    第四章(数组) 编程题 1
    第三章(循环) 编程题 3
    低功耗蓝牙 ATT/GATT/Service/Characteristic 规格解读
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/11494862.html
Copyright © 2011-2022 走看看