1. 程式人生 > >洛谷 P1731 [NOI1999]生日蛋糕

洛谷 P1731 [NOI1999]生日蛋糕

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;
}
一通亂搞的剪枝