圖論小結(三)-剪

BFS 優化:

雙向BFS注意點:

  1. 每輪遍歷整層;
  2. 每輪選取已搜索點數少的一邊搜一層;
DFS 優化:

剪枝
這裏以洛谷的p1731生日蛋糕爲例
題目背景
7月17日是Mr.W的生日,ACM-THU爲此要製作一個體積爲Nπ的M層生日蛋糕,每層都是一個圓柱體。設從下往上數第i(1<=i<=M)層蛋糕是半徑爲Ri, 高度爲Hi的圓柱。當i<M時,要求Ri>Ri+1, R i>Ri+1; Hi>Hi+1,
i>Hi+1
由於要在蛋糕上抹奶油,爲儘可能節約經費,我們希望蛋糕外表面(最下一層的下底面除外)的面積Q最小。令Q= Sπ
請編程對給出的N和M,找出蛋糕的製作方案(適當的Ri和Hi的值),使S最小。(除Q外,以上所有數據皆爲正整數)
數據
N(N<=20000),表示待制作的蛋糕的體積爲Nπ;M(M<=15),表示蛋糕的層數爲M。
時空限制:1000ms / 128MB
DFS方式
l:當前層數
r:當前半徑(最大等於體積的平方根)
h:當前高度(最大等於體積)
rv:當前剩餘體積
ts:當前總側面積
初始:dfs(0, n^0.5, n, n, 0);

void dfs(int l, int r, int h, int rv, int ts)
{
  loop()
  {
    // 剪枝
    dfs(l+1, r-1, h-1, rv-nowV, ts+nowV);
  }
}

剪枝策略

  1. 當前面積+剩餘層數最小面積 > 最優解,剪
  2. 當前體積 < 剩餘層數最小體積,剪
  3. 當前體積 > 剩餘層數最大體積,剪

剩餘層數最小面積與剩餘的層數有關,而同一層數會重複使用,所以可以考慮開個數組,預處理一下。而層數最多隻有15層,15個狀態,果斷預處理;
剩餘層數最小面積也只與剩餘層數有關,同理也會重複使用,預處理;
剩餘層數最大體積與剩餘層數、當前半徑、高度都有關,狀態數量最多有15x141x20‘000,如果開個int數組需要超過160Mb空間,暴空間了。這裏有個問題,就是經過前兩種剪枝後,加上條件限制,我們對這個數組的使用是很稀疏的,所以完全沒有必要預處理,只需要在dfs中計算就好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章