記憶化搜尋記憶化搜尋:演算法上依然是搜尋的流程,但是搜尋到的一些解用動態規劃的那種思想和模式作一些儲存。一般說來,動態規劃總要遍曆所有的狀態,而搜尋可以排除一些無效狀態。更重要的是搜尋還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求解一個狀態,就將它的解儲存下來,以後再次遇到這個狀態的時候,就不必重新求解了。 這種方法綜合了搜尋和動態規劃兩方面的優點,因而還是很有實用價值的。雖然不能使用傳統意義上的動態規劃解決本題,但動態規劃的思想仍然能起到作用。搜尋相對於動態規劃最大的劣勢無非就是重複計運算元結構,所以我們在搜尋的過程中,對於每一個子結構只計算一次,之後儲存到數組裡,以後要用到的時候直接調用就可以了,這就是我要介紹的記憶化搜尋。記憶化搜尋的實質是動態規劃,效率也和動態規劃接近,形式是搜尋,簡單直觀,代碼也容易編寫,不需要進行什麼拓撲排序了。可以歸納為:記憶化搜尋=搜尋的形式+動態規劃的思想
如下例:
#include<stdio.h>#include<stdlib.h>#include<string.h>//using namespace std;int arr[22][22][22];int sum(int a,int b,int c){if(a<=0||b<=0||c<=0){return 1;}else if(a>20||b>20||c>20){return arr[20][20][20]=sum(20,20,20);}else if(arr[a][b][c]){return arr[a][b][c];}else if(a<b&&b<c){return arr[a][b][c]=sum(a,b,c-1)+sum(a,b-1,c-1)-sum(a,b-1,c);}else{return arr[a][b][c]=sum(a-1,b,c)+sum(a-1,b-1,c)+sum(a-1,b,c-1)-sum(a-1,b-1,c-1);}}int main(){int a,b,c,m;while(scanf("%d%d%d",&a,&b,&c)!=EOF&&!(a==-1&&b==-1&&c==-1)){memset(arr,0,sizeof(arr));m=sum(a,b,c);printf("w(%d, %d, %d) = %d\n",a,b,c,m);}return 0;}