sicily 1219(記憶化搜尋)

2021-07-03 02:06:08 字數 1417 閱讀 5471

sicily 1219

解題思路:

博弈題,用搜尋來做。但是,如果用普通的搜尋來做的話,是會超時的——複雜度大約是o( n^n ),所以需要採用記憶化搜尋的方法(其實差不多就是動態規劃了,但是這裡是樹形dp)。

狀態:

用集合s表示現在樹的狀態,i 表示現在輪到誰進行砍邊,dp[ s ][ i ]表示最優值。集合s可以用二進位制來表示,即001表示現在還剩下第0條邊。

狀態轉移:

1)a的目標是取最大值,b的目標是取最小值,我們在推導當前狀態的最優解時,需要分兩種情況考慮!即a得維護較大值,b維護較小值。

2)需要考慮沒有邊可以砍的情況——在當前玩家無法更新的情況下,直接尋找另乙個玩家的解。

預處理:

一切為了時間——題目存在同時砍多條邊的情況(只得到離根最近的一條邊的值),所以我們可以在搜尋前找到每一條邊的影響邊,即砍掉這條邊之後什麼邊會消失!

**:

#include 

#include

#include

#include

#include

#define inf 0x3f3f3f3f

using namespace std;

int n,c[25][25],w[25][25],v[25];

int dp[1

<<20][2],flag[25],pre[25];

void dfs(int

index) //預處理

}}int sol(int

index,int player) //記憶化搜尋

}if(player==1) //a玩家

if(player==-1) //b玩家

return dp[index][(player+1)/2];

}int main()

pre[0]=-1,dfs(0); //預處理

flag[0]=0;

memset(dp,inf,sizeof(dp));

int ans=sol((1

<<(n-1))-1,1);

printf("%d\n",ans);

}return

0;}

總結:

挺典型的記憶化搜尋的題目,而這道題最大的亮點是可以用二進位制來優化時間複雜度。果然太久沒做題了有點生疏了,想起今年的校賽,確實很可惜,明年一定要打進省賽!

記憶化搜尋

演算法上依然是搜尋的流程,但是搜尋到的一些解用 動態規劃 的那種思想和模式作一些儲存。一般說來,動態規劃總要遍歷所有的狀態,而搜尋可以排除一些無效狀態。更重要的是搜尋還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求...

記憶化搜尋

記憶化搜尋 演算法上依然是搜尋的流程,但是搜尋到的一些解用動態規劃的那種思想和模式作一些儲存。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求解乙個狀態,就將它的解儲存下來,以後再次遇到這個狀態的時候,就不必重新求解了。例1.題目描述 給從左至右排好隊的小朋友們分糖果,要求 1.每個小朋友都...

記憶化搜尋

原文 感謝作者。一.動態規劃 動態規劃 dynamic programming 與 分治思想 有些相似,都是利用將問題分 為子問題,並通過合併子問題的解來獲得整個問題的解。於 分治 的不同之處在 於,對於乙個相同的子問題動態規劃演算法不會計算第二次,其實現原理是將每乙個計算過的子問題的值儲存在乙個表...