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 與 分治思想 有些相似,都是利用將問題分 為子問題,並通過合併子問題的解來獲得整個問題的解。於 分治 的不同之處在 於,對於乙個相同的子問題動態規劃演算法不會計算第二次,其實現原理是將每乙個計算過的子問題的值儲存在乙個表...