生日蛋糕
时间限制: 1 Sec 内存限制: 128 MB提交: 2 解决: 2
[提交] [状态] [讨论版] [命题人:admin]
题目描述

设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i<M时,要求Ri>Ri+1且Hi>Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
令Q= Sπ,请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。(除Q外,以上所有数据皆为正整数)
输入
有两行,第一行为N(N<=10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M<=20),表示蛋糕的层数为M。
输出
仅一行,是一个正整数S(若无解则S=0)。
样例输入
100
2
样例输出
68
提示
体积V=πR2H
侧面积A’=2πRH
底面积A=πR2
题意
找每一层合适的r,h,使得最后的面积s最小。输出s。
分析
真的是毫无头绪,要不是在搜索专题真不觉得是个搜索题。
想明白了还是挺简单的。直接的dfs不可行,需要一些剪枝。
1、设下一层的最大体积为v,剩余体积为left_v,还剩余x层未搜索,如果x*v<left_v。一句话就是:剩下的体积用不完了。
2、如果当前的面积已经比之前记录的最小面积大,那就没有必要继续搜了。

/// author:Kissheart /// #include<stdio.h> #include<algorithm> #include<iostream> #include<string.h> #include<vector> #include<stdlib.h> #include<math.h> #include<queue> #include<deque> #include<ctype.h> #include<map> #include<set> #include<stack> #include<string> #define INF 0x3f3f3f3f #define FAST_IO ios::sync_with_stdio(false) const double PI = acos(-1.0); const double eps = 1e-6; const int MAX=1e5+10; const int mod=1e9+7; typedef long long ll; using namespace std; #define gcd(a,b) __gcd(a,b) inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;} inline ll inv1(ll b){return qpow(b,mod-2);} inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;} inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;} //freopen( "in.txt" , "r" , stdin ); //freopen( "data.txt" , "w" , stdout ); int n,m; int ans; void dfs(int x,int left_v,int pre_r,int pre_h,int sum) { if(!x && !left_v) { if(ans) ans=min(sum,ans); else ans=sum; return ; } if(x*(pre_r-1)*(pre_r-1)*(pre_h-1)<left_v && x!=m) return ; if(x<=0 || left_v<=0 || (sum>=ans && ans)) return ; for(int i=pre_r-1;i>=x;i--) { for(int j=pre_h-1;j>=x;j--) { int s=2*i*j; int v=i*i*j; if(x==m) s+=i*i; if(2*left_v/i+sum>=ans && ans) continue; dfs(x-1,left_v-v,i,j,sum+s); } } } int main() { scanf("%d%d",&n,&m); dfs(m,n,1000,100,0); printf("%d ",ans); return 0; }