Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 14120 | Accepted: 4971 |
Description
設從下往上數第i(1 <= i <= M)層蛋糕是半徑爲Ri, 高度爲Hi的圓柱。當i < M時,要求Ri > Ri+1且Hi > Hi+1。
由於要在蛋糕上抹奶油,爲儘可能節約經費,我們希望蛋糕外表面(最下一層的下底面除外)的面積Q最小。
令Q = Sπ
請編程對給出的N和M,找出蛋糕的製作方案(適當的Ri和Hi的值),使S最小。
(除Q外,以上所有數據皆爲正整數)
Input
Output
Sample Input
100 2
Sample Output
68
Hint
體積V = πR2H
側面積A' = 2πRH
底面積A = πR2
Source
給定蛋糕的體積,求解蛋糕的最小面積。其中有較高層的r和h都要小於較低一層的限制。
剪枝參考http://www.cnblogs.com/rainydays/p/3523162.html
共有三種
按着上述的剪枝來做了,卻還是超時嚴重甚至本機運行都成很大問題
發現是最主要的兩步剪枝沒做好,原先TLE的做法在下面代碼的註釋裏,
原先的剪枝是在本層剪上一層的枝,本以爲不成問題,估計是狀態空間真的太大了
所以以後剪枝還是要就剪本層遞歸的
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <functional>
#define maxn 5005
using namespace std;
int n,m,s;
int check2[25],check3[25];
void calcu()
{
memset(check2,0,sizeof check2);
memset(check3,0,sizeof check3);
check2[1]=2;
check3[1]=1;
for(int i=2;i<25;i+=1){
check2[i]=check2[i-1]+2*i*i;
check3[i]=check3[i-1]+i*i*i;
cout<<check3[i]<<" ";
}
cout<<"\n";
}
void dfs(int layer,int r,int h,int v,int nows)
{
if(layer==m){
if(v+r*r*h==n&&nows+2*r*h<s){
s=nows+2*r*h;
}
return ;
}
else if(n-v-r*r*h<check2[m-layer]) return ; //n-v<check2[m-layer+1]
else if(s-nows-2*r*h<check3[m-layer]) return ; //s-nows<check3[m-layer+1]
else if(2*(n-v)/r>s-nows) return ;
else{
for(int i=m-layer;i<r;i+=1){
for(int j=m-layer;j<h;j+=1){
dfs(layer+1,i,j,v+r*r*h,nows+2*r*h);
}
}
}
}
int main()
{
s=99999999;
calcu();
scanf("%d %d",&n,&m);
for(int i=(int)sqrt(n)+1;i>=1;i-=1){
for(int j=n;j>=1;j-=1){
dfs(1,i,j,0,i*i);
}
}
if(s==99999999) printf("0\n",s);
else printf("%d\n",s);
return 0;
}
//s 57 85
//i 3 2
//j 8 7