poj 1190 生日蛋糕 , 強剪枝

來源:互聯網
上載者:User

標籤:style   blog   http   color   資料   os   

題意:

製作一個體積為Nπ(N<=10000)的M(M<=20)層生日蛋糕,每層都是一個圓柱體。 

設從下往上數第i(1 <= i <= M)層蛋糕是半徑為Ri, 高度為Hi的圓柱。當i < M時,要求Ri > Ri+1且Hi > Hi+1。 
由於要在蛋糕上抹奶油,為儘可能節約經費,我們希望蛋糕外表面(最下一層的下底面除外)的面積Q最小。 
令Q = Sπ 
請編程對給出的N和M,找出蛋糕的製作方案(適當的Ri和Hi的值),使S最小。 

(除Q外,以上所有資料皆為正整數) 


分析:

表面積只和底面圓面積和各層側面積有關

Q = Sπ

S = R1*R1 + 2*sigma(Ri*Hi(1<=i<=M))

N = sigma(Ri*Ri*Hi(1<=i<=M))


狀態(i, Ri, Hi, Si-1, Di-1)  轉移---> (i+1, Ri+1, Hi+1, Si, Di)

枚舉變數 Ri,Hi,為了減少狀態數,就要減少Ri,Hi的枚舉範圍。

最初一定有: 

M-i<= Ri+1< Ri

M-i<= Hi+1< Hi


剪枝一:

預先計算

minS[i]  表示從上到下第一層到第i層最少要用去的S

minN[i]  表示從上到下第一層到第i層最少要用去的N

則有剪枝:

     Si-1 +minS[m-i] >= best   //最佳化剪枝

     Di-1 + minN[m-i] >= N      //可行性剪枝


剪枝二:

從k層到m層增加的側面積


Si-1 + 2*(N-Di-1)/Ri >=  best  //最佳化剪枝


剪枝三:

如果先枚舉Ri, 則Hi的上界 maxH = min(Hi  -1, N  -   Si-1   -   minN[M-i-1]) / (Ri*Ri)   )   //可行性剪枝

//先枚舉Hi一樣。。


#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <string>#include <set>#include <map>using namespace std;#define min(a,b) (a) <(b) ? (a):(b)#define INF 0x3f3f3f3fint minN[25], minS[25];int N, M, Min;void init(){    int i;    minN[0] = minS[0] = 0;    for(i=1; i<=21; ++i)    {        minS[i] = minS[i-1] + 2 * i * i;        minN[i] = minN[i-1] + i * i * i;    }}void dfs(int k, int r, int h, int sums, int sumv){    if(k==M){        if(sumv == N && sums < Min)        {            Min = sums;        }        return ;    }    if(sums + minS[M-k] > Min ||sumv + minN[M-k] > N||2*(N-sumv)/r + sums >= Min)        return ;    for(int i=r-1; i>=M-k; --i)    {        if(k==0) sums = i * i;        int maxH = min( h-1, (N-sumv-minN[M-k-1])/(i*i) );        for(int j=maxH; j>=M-k; --j)            dfs(k+1, i, j, sums + 2 * i * j, sumv + i * i * j);    }}int main(){    init();    while(cin>>N>>M)    {        Min = INF;        dfs(0, N, N, 0, 0);  //K, R, H, SUMS, SUMV        if(Min<INF)            cout<<Min<<endl;        else            cout<<0<<endl;    }    return 0;}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.