这个题采用了记忆化搜索(Memory search)
topic’s Link ----》 Function
Firstly:
了解一下记忆化搜索:记忆化搜索是一种通过记录已经遍历过的状态的信息,从而避免对同一状态重复遍历的搜索实现方式。
- 其中从而避免对同一状态重复遍历的搜索实现方式这个一个特点在本题体现在
if(dp[a][b][c] != -1; return dp[a][b][c]
其实就是当这个点被搜到了,然后你发现这个点其实已经被搜索过了,就直接返回他的值,从而就避免了被重复搜索。
注意: 因为记忆化搜索确保了每个状态只访问一次,它也是一种常见的动态规划实现方式。
Other matters
这个题目值得注意的是,超过二十就用20来算,所以我们的数组范围就会设置为
long long dp[25][25][25]
值得注意的是这个题目的范围是[-9223372036854775808,9223372036854775807]
因此就要如下的初始化
cout << "w(" << a << ", " << b << ", " << c << ')' << ' ' << '=' << ' ';
if(a > 20) a = 21;
if(b > 20) b = 21;
if(c > 20) c = 21;//上面的三个就是防止数组越界 把他们都写成21就好了
cout << dfs(a, b, c) << endl;
At last:
the ac code is:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 25;
typedef long long ll;
ll dp[N][N][N];
ll dfs(ll a, ll b, ll c)//Memory search
{
if(a <= 0 || b <= 0 || c <= 0) return 1;
else if(a > 20 || b > 20 || c > 20) dp[a][b][c] = dfs(20, 20, 20);
else if(dp[a][b][c] != -1) return dp[a][b][c];
else if(a < b && b < c)
dp[a][b][c] = dfs(a, b, c - 1) + dfs(a, b - 1, c - 1) - dfs(a, b - 1, c);
else
dp[a][b][c] = dfs(a - 1, b, c) + dfs(a - 1, b - 1, c) + dfs(a - 1, b, c - 1) - dfs(a - 1, b - 1, c - 1);
return dp[a][b][c];
}
int main()
{
memset(dp, -1, sizeof dp);
ll a, b, c;
while(cin >> a >> b >> c)
{
if(a == -1 && b == -1 && c == -1) break;
cout << "w(" << a << ", " << b << ", " << c << ')' << ' ' << '=' << ' ';
if(a > 20) a = 21;
if(b > 20) b = 21;
if(c > 20) c = 21;
cout << dfs(a, b, c) << endl;
}
return 0;
}