1. 程式人生 > >我對於搜索算法的慢慢摸索

我對於搜索算法的慢慢摸索

尋找 pro 基礎 慢慢 pan i++ n) -s max

高中的時候好像什麽都沒學會的樣子,提到搜索腦子裏雲裏霧裏一般。還能怎麽著,練唄。

找到了一道dfs基礎題,http://poj.org/problem?id=1190

果然是完全沒有思路,參照大佬的題解,弄懂了大佬的思路。

 1 //生日蛋糕
 2 //poj 1190 
 3 #include<stdio.h>
 4 #include<math.h>
 5 #define INF 1000000
 6 int mins[21],minv[21];//從第一層到第i層的最小體積minv和最小面積mins 
 7 #define min(a,b) ((a)<(b)?(a):(b))
 8 int n,m,best;
9 void init(){ 10 int i; 11 for(i=1;i<21;i++){ 12 mins[i]=mins[i-1]+2*i*i;//因為半徑和高必須是正整數,又要遞增,所以i作為 13 minv[i]=minv[i-1]+i*i*i; //第i層的半徑和高顯然是最小的情況。 14 } 15 } 16 17 //核心算法:搜索。從第m層開始往上搜索,一直到第0層結束。 18 // deep表示該層層數,sums是從m到deep+1得到的表側面積,sumv是體積,r是deep+1的半徑,h是deep+1的高度 19 void
dfs(int deep,int sums,int sumv,int r,int h){ 20 if(deep==0){ 21 if(sumv==n&&sums<best)best=sums; 22 return; 23 } 24 if(sums+mins[deep]>best||sumv+minv[deep]>n||2*(n-sumv)/r+sums>=best)return; 25 //幾個剪枝 26 //第一跟第二:表面積顯然大於最優解或者是體積顯然超過n 27 //第三個:n-sumv=h[1]*r[1]*r[2]+……+h[deep]*r[deep]*r[deep]<h[1]*r[1]*r+……+h[deep]*r[deep]*r
28 //兩邊同除r,*2,可以化為這樣的形式 29 int i,j,maxh; 30 for(i=r-1;i>=deep;i--){//i是遍歷deep層的半徑,從最大到最小 31 if(deep==m)sums=i*i;//sums的初值 32 maxh =min((n-sumv-minv[deep-1])/(i*i),h-1);//從這兩個數中尋找maxh的最大值,這兩個都是頂點 33 for(j=maxh;j>=deep;j--)dfs(deep-1,sums+2*i*j,sumv+i*i*j,i,j); 34 } 35 } 36 main(){ 37 best=INF; 38 scanf("%d%d",&n,&m); 39 dfs(m,0,0,sqrt(n)+1,n+1);//初始條件m+1層的半徑為h等於1時得到的半徑,h是r等於1時得到的半徑。 40 if(best==INF)printf("0\n"); 41 else printf("%d\n",best); 42 return 0; 43 }

這道題的主要考點應該是第三處剪枝(大佬是這麽說的),但是與我而言,我連最基礎的搜索的板子都不會。還能怎麽著,練唄。

我對於搜索算法的慢慢摸索