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

    题目背景

    7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层

    生日蛋糕,每层都是一个圆柱体。

    设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i<M时,要求R_i>R_{i+1}Ri>Ri+1H_i>H_{i+1}Hi>Hi+1

    由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。

    令Q= Sπ

    请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。

    (除Q外,以上所有数据皆为正整数)

    题目描述

    输入输出格式

    输入格式:

     

    有两行,第一行为N(N<=20000),表示待制作的蛋糕的体积为Nπ;第二行为M(M<=15),表示蛋糕的层数为M。

     

    输出格式:

     

    仅一行,是一个正整数S(若无解则S=0)。

     

    输入输出样例

    输入样例#1: 复制
    100
    2
    
    输出样例#1: 复制
    68
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,m,ans=0x7f7f7f7f;
    int r[16],h[16];
    int mins[16],minv[16];
    void dfs(int r,int h,int deep,int s,int v){
        if(s>ans)    return ;//第一层剪枝 
        if(v==n&&deep>0)    return ;//第二层剪枝 
        if(v+minv[deep]>n)    return ;
        if(s+mins[deep]>ans)    return ;
        if(v==n&&deep==0){
            ans=min(ans,s);
            return ;
        }
        for(int i=r;i>=deep;i--)
            for(int j=h;j>=deep;j--){
                if(deep==m)    dfs(i-1,j-1,deep-1,s+2*i*j+i*i,v+j*i*i);
                else    dfs(i-1,j-1,deep-1,s+2*i*j,v+j*i*i);
            }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            mins[i]=mins[i-1]+i*i*2;
            minv[i]=minv[i-1]+i*i*i;
        }
        dfs(sqrt(n),sqrt(n),m,0,0);
        if(ans==0x7f7f7f7f)    printf("0");
        else cout<<ans;
    }
    50分dfs
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,m,ans=0x7f7f7f7f;
    int r[16],h[16];
    int mins[16],minv[16];
    void dfs(int r,int h,int deep,int s,int v){
        if(s>ans)    return ;//第一层剪枝 
        if(v==n&&deep>0)    return ;//第二层剪枝 
        if(v+minv[deep]>n)    return ;
        if(s+mins[deep]>ans)    return ;
        if(s+2*(n-v)/(r+1)>=ans)    return ;
        if(v==n&&deep==0){
            ans=min(ans,s);
            return ;
        }
        if(deep==0)    return ;
        for(int i=r;i>=deep;i--){
            int yy=min((n-v-minv[deep-1])/(i*i),h);
            for(int j=yy;j>=deep;j--){
                if(deep==m)    dfs(i-1,j-1,deep-1,s+2*i*j+i*i,v+j*i*i);
                else    dfs(i-1,j-1,deep-1,s+2*i*j,v+j*i*i);
            }
        }    
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            mins[i]=mins[i-1]+i*i*2;
            minv[i]=minv[i-1]+i*i*i;
        }
        dfs(sqrt(n),sqrt(n),m,0,0);
        if(ans==0x7f7f7f7f)    printf("0");
        else cout<<ans;
    }
    一通乱搞的剪枝
     
  • 相关阅读:
    Leetcode 230 Kth Smallest Element in a BST
    codeforces Round #259(div2) C解题报告
    poj 3041(最大匹配问题)
    SpringMVC从Controller跳转到还有一个Controller
    倒计时相关函数 php
    HDU 1575 Tr A(矩阵高速幂)
    poj3468 A Simple Problem with Integers
    奇妙的自慰帽子
    Android 用户登录界面
    泛泰A860(高通8064 cpu 1080p) 刷4.4专用中文recovery TWRP2.7.1.2版(三版通刷)
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/9898619.html
Copyright © 2011-2022 走看看