題目
最簡單記憶化搜索
記憶化搜索:算法上依然是搜索的流程,但是搜索到的一些解用動態規劃的那種思想和模式作一些保存。
一般說來,動態規劃總要遍歷所有的狀態,而搜索可以排除一些無效狀態。搜索還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。
記憶化算法在求解的時候還是按着自頂向下的順序,但是每求解一個狀態,就將它的解保存下來,
以後再次遇到這個狀態的時候,就不必重新求解了。
別人代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll rpt[25][25][25];
ll w(ll a,ll b,ll c)
{
if(a<=0||b<=0||c<=0) return 1;
else if(rpt[a][b][c]!=0) return rpt[a][b][c];
else if(a>20||b>20||c>20) rpt[a][b][c]=w(20,20,20);
else if(a<b&&b<c) rpt[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
else rpt[a][b][c]=w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1);
return rpt[a][b][c];
}
int main()
{
ll a,b,c;
while(scanf("%lld%lld%lld",&a,&b,&c)==3){
memset(rpt,0,sizeof(rpt));
if(a==-1&&b==-1&&c==-1) break;
printf("w(%lld, %lld, %lld) = ",a,b,c);
if(a>20) a=21;
if(b>20) b=21;
if(c>20) c=21;
printf("%lld\n",w(a,b,c));
}
return 0;
}
定義記憶宏
看題解看到的,感覺很實用,代碼清晰簡單,附上AC代碼
我的代碼
#include <stdio.h>
#include <string.h>
#include <string>
#include <utility>
#include <iostream>
#include <cstdlib>
const int MAXN = 100010;
using namespace std;
//記憶宏,w被求過,就返回w,否則將求得的值先賦給w然後返回
#define W_(x,y,z) (w_[x][y][z] ? w_[x][y][z] : w_[x][y][z] = w(x, y, z))
int w_[25][25][25];
int w(int a,int b,int c){
int ans;
if(a<=0||b<=0||c<=0){
ans=1;
return ans;
}
else if(a>20||b>20||c>20){
return 1048576;//w(20,20,20)
}
if(a < b && b < c)
return W_(a,b,c-1)+W_(a,b-1,c-1) - W_(a,b-1,c);
return W_(a-1,b,c)+W_(a-1,b-1,c)+W_(a-1,b,c-1) - W_(a-1,b-1,c-1);
}
int main(){
int a,b,c;
while(cin>>a>>b>>c){
if(a==-1&&b==-1&&c==-1)break;
cout<<"w("<<a<<", "<<b<<", "<<c<<") = "<<w(a,b,c)<<endl;
}
return 0;
}