• Luogu P1731 生日蛋糕(dfs剪枝)


     
    #include<cstdio>
    #include<cmath>
    using namespace std;
    
    int n,m,r[55],h[55],minn=0x7ffffff;
    
    inline int min(int x,int y){return x>y?y:x;}
    
    inline void dfs(int now,int rest,int s,int z){
        if(rest==0&&now==m+1){
            s+=r[1]*r[1];
            minn=min(minn,s);
            return;
        }
        if(rest==0||now==m+1)return;
        if(s+r[1]*r[1]>=minn)return;//剪枝
        if(r[now-1]*r[now-1]*h[now-1]*z<rest)return;//剪枝
        for(int i=r[now-1]-1;i>=z;i--){
            for(int j=h[now-1]-1;j>=z;j--){
                if(i*i*j<=rest){
                    r[now]=i;
                    h[now]=j;
                    dfs(now+1,rest-i*i*j,s+(2*i*j),z-1);
                    r[now]=0;
                    h[now]=0;
                }
            }
        }
    }
    
    int main(){
        /*
      for r[1] h[1]:
        v=r*r*h
        v<n r>=m h>=m .`. r*r>=m*m 
         h=v/(r*r)  .`. h max=vmax/(r*r)min=n/(m*m)  
        r*r=v/h  .`. r*r max=vmax/hmin=n/m
      */
        scanf("%d%d",&n,&m);
        r[0]=int(sqrt(n/m))+1;
        h[0]=n/(m*m)+1;
        dfs(1,n,0,m);
        if(minn==0x7ffffff)printf("%d
    ",0);
        else printf("%d
    ",minn);
    }
    1.代码参考洛谷一位巨佬的题解,不过ta有几个地方很莫名其妙O_O ,于是我改动了一些东西。

    2.例如,r[0]与h[0]的值应该分别取(int)sqrt(n/m)与n/(m*m),如果都取sqrt(n)的话,有点不太好理解。手推的过程在注释里面。
    但为什么我要分别加上1呢?难道不是更费吗?
    起因是这样的:如果你看过洛谷题解,你一定会发现,大部分人的程序,当n和m较小时,都输出0,即没搜到。
    根据洛谷上另一个巨佬的评论,你会发现,这是精度问题导致的。
    (其实我觉得对于我的r[0]与h[0],当m=1时还有一个原因可能是r[1]h[1]有最大值r[0]h[0],而不是趋近最大值r[0]h[0],而我们在dfs中r[1]初值是r[0]-1)
    因此,像这样稍微扩大一下搜索范围,对于1 1这组很小的数据就可以顺利输出3了。
    而这一微小的鬼畜操作并不会对较大测试点造成多大影响。
    (其实我发现如果r[0]与h[0]取得过大,例如n,会全输出0 QAQ 哪位巨佬可以告诉我呀?)

    3.其实dfs的第三个if中,s+r[1]*r[1]>=minn是return的必要不充分条件,因为没有记上之后拼的侧面积。
    因此,为了让它更快,或许也可以往左边式子里面加上一些鬼畜的玩意,例如加上z,2*z,2*z*z等等。
    (好吧我一开始就是洛谷巨佬题解的这个地方没看懂)

    4.好吧这题实在是太神奇了,我在洛谷上交了22次以上QAQ

    5.参考文献:https://www.luogu.org/blog/zzmblog/solution-p1731
  • 相关阅读:
    第二阶段冲刺第一天
    第一次团队绩效评估
    其他团队对本团队评价的总结
    对其他团队的评价
    团队博客的检查结果
    站立会议第十天
    站立会议第九天
    站立会议第八天
    站立会议第七天
    团队站立会议10
  • 原文地址:https://www.cnblogs.com/Y15BeTa/p/luogu1731.html
Copyright © 2020-2023  润新知