洛谷P1464 Function 题解
Function
题目描述
对于一个递归函数 \(w(a,b,c)\)
- 如果 \(a \le 0\) 或 \(b \le 0\) 或 \(c \le 0\) 就返回值 \(1\)。
- 如果 \(a>20\) 或 \(b>20\) 或 \(c>20\) 就返回 \(w(20,20,20)\)
- 如果 \(a<b\) 并且 \(b<c\) 就返回 \(w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,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)\)
这是个简单的递归函数,但实现起来可能会有些问题。当 \(a,b,c\) 均为 \(15\) 时,调用的次数将非常的多。你要想个办法才行。
注意:例如 \(w(30,-1,0)\) 又满足条件 \(1\) 又满足条件 \(2\),请按照最上面的条件来算,答案为 \(1\)。
输入格式
会有若干行。
并以 \(-1,-1,-1\) 结束。
输出格式
输出若干行,每一行格式:
w(a, b, c) = ans
注意空格。
样例 #1
样例输入 #1
1 1 1
2 2 2
-1 -1 -1
样例输出 #1
w(1, 1, 1) = 2
w(2, 2, 2) = 4
提示
数据规模与约定
保证输入的数在 \([-9223372036854775808,9223372036854775807]\) 之间,并且是整数。
保证不包括 \(-1, -1, -1\) 的输入行数 \(T\) 满足 \(1 \leq T \leq 10 ^ 5\)。
题解
思路
这道题其实就是一道模拟+记忆化的题目,根据原有题目给定的步骤写一个递归函数出来,再稍微加上一点记忆化搜索即可。
代码
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;
ll A, B, C;
ll mp[35][35][35];
ll w(ll a, ll b, ll c) {
if(a <= 0 || b <= 0 || c <= 0) return 1;
else if(a > 20 || b > 20 || c > 20) return w(20, 20, 20);
else if(a < b && b < c) {
if(!mp[a][b][c - 1]) {
mp[a][b][c - 1] = w(a, b, c - 1);
}
if(!mp[a][b - 1][c - 1]) {
mp[a][b - 1][c - 1] = w(a, b - 1, c - 1);
}
if(!mp[a][b - 1][c]) {
mp[a][b - 1][c] = w(a, b - 1, c);
}
mp[a][b][c] = mp[a][b][c - 1] + mp[a][b - 1][c - 1] - mp[a][b - 1][c];
} else {
if(!mp[a - 1][b][c]) {
mp[a - 1][b][c] = w(a - 1, b, c);
}
if(!mp[a - 1][b - 1][c]) {
mp[a - 1][b - 1][c] = w(a - 1, b - 1, c);
}
if(!mp[a - 1][b][c - 1]) {
mp[a - 1][b][c - 1] = w(a - 1, b, c - 1);
}
if(!mp[a - 1][b - 1][c - 1]) {
mp[a - 1][b - 1][c - 1] = w(a - 1, b - 1, c - 1);
}
mp[a][b][c] = mp[a - 1][b][c] + mp[a - 1][b - 1][c] + mp[a - 1][b][c - 1] - mp[a - 1][b - 1][c - 1];
}
return mp[a][b][c];
}
int main() {
while(1) {
cin >> A >> B >> C;
if(A == -1 && B == -1 && C == -1) break;
cout << "w(" << A << ", " << B << ", " << C << ") = " << w(A, B, C) << endl;
}
return 0;
}