還是被這個立體的結構嚇到了,隔了半年才a.
題目描述
7月17日是mr.w的生日,acm-thu為此要製作乙個體積為nπ的m層
生日蛋糕,每層都是乙個圓柱體。
設從下往上數第i(1<=i<=m)層蛋糕是半徑為ri, 高度為hi的圓柱。當ir_i>r_ri>ri+1且h_i>h_hi>hi+1。
由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面(最下一層的下底面除外)的面積q最小。
令q= sπ
請程式設計對給出的n和m,找出蛋糕的製作方案(適當的ri和hi的值),使s最小。
(除q外,以上所有資料皆為正整數)
輸入格式:
有兩行,第一行為n(n<=20000),表示待製作的蛋糕的體積為nπ;第二行為m(m<=15),表示蛋糕的層數為m。
輸出格式:
僅一行,是乙個正整數s(若無解則s=0)。
輸入樣例:
100
2
輸出樣例:
68
解題思路:
1.搜尋要搜什麼?
(1)符合體積要求的最小表面積
2.搜尋記錄什麼?
(1)已使用體積
(2)已使用面積
(3)第幾層
(4)上一層半徑
(5)上一層高度
3.如何剪枝?
可行性剪枝:
(1)當前體積+預算最小體積》n
最優性剪枝:
(1)當前表面積+預算最小側面積》ans
(2)(2*(n-v)/r)+s>ans根據體積公式和面積公式求。
解釋:如果當前表面積+預算最小側面積(取極限)>ans
上下界剪枝:
(1)r和h的範圍可以確定的,這裡我就不記錄了,可以根據體積公式求得。
優化搜尋順序:
(1)從大到小迴圈,減少搜尋狀態。
**:
#include#define ll long long#define r register
using
namespace
std;
const
int n=20
;int n,m,minh[n],minr[n],sums[n],sumv[n],ans=0x3f3f3f3f
;inline
intread()
while(ch>='
0'&&ch<='
9') s=s*10+ch-'
0',ch=getchar();
return s*w;
}inline
void dfs(r int dep,r int lstr,r int lsth,r int s,r int
v)
if(v+sumv[dep]>n)return
;
if(s+sums[dep]>=ans)return
;
if((2*(n-v)/lstr)+s>ans)return
;
for(r int i=min(lstr-1,(int)sqrt(n-v));i>=minr[dep];i--)
for(r int j=min(lsth-1,(n-v)/(i*i));j>=minh[dep];j--)
dfs(dep-1,i,j,s+2*i*j,v+i*i*j);
}int
main()
for(r int i=(int)sqrt(n);i>=minr[m];i--)
for(r int j=n/(i*i);j>=minh[m];j--)
dfs(m-1,i,j,i*i+2*i*j,i*i*j);
if(ans==0x3f3f3f3f
) printf("0
");else printf("%d"
,ans);
return0;
}
noi 1999 生日蛋糕
題目描述 4月16日是nanae的生日,josnch為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當i m時,要求ri ri 1且hi hi 1。由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面 最下一層的下...
NOI1999 生日蛋糕
noi1999 生日蛋糕 7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為ri,高度為hi的圓柱。當i時,要求ri ri 1且hi hi 1。由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面 ...
NOI1999 生日蛋糕
7月17日是mr.w的生日,acm thu為此要製作乙個體積為n 的m層 生日蛋糕,每層都是乙個圓柱體。設從下往上數第i 1 i m 層蛋糕是半徑為 r i 高度為 h i 的圓柱。當i r i r 且 h i h 由於要在蛋糕上抹忌廉,為盡可能節約經費,我們希望蛋糕外表面 最下一層的下底面除外 的...