题目链接:P1464 Function - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这个题题目都说的很清楚是递归了,然后在里面还很用心的提示你这是个简单的递归函数,但实现起来可能会有些问题。当 a,b,ca,b,c 均为 1515 时,调用的次数将非常的多。你要想个办法才行。这个是什么,只要稍微多写两道题,或者看到昨天的博客,就可以知道,这玩意就是记忆化搜索,即用空间换时间,开辟数组。然后思路也很明确,特别简单,那么我们先上一个错误版代码
#include<iostream>
#include<cstring>
using namespace std;
long long f[25][25][25];
long long w(int a, int b, int c) {
if (f[a][b][c] != -1) return f[a][b][c];
if (a <= 0 || b <= 0||c<=0)return 1;
if (a > 20 || b > 20 || c > 20)return w(20, 20, 20);
return f[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);
}
int main() {
memset(f, -1, sizeof(f));
long long a, b, c;
while (cin >> a >> b >> c) {
if (a == b && b == c && a == -1) break;
cout << "w("<<a<<", " <<b<<", " <<c<<") = " << w(a, b, c) << "\n";
}
return 0;
}
这是为什么呢,没错数组越界访问,有的童鞋问“为啥?比20大的我不是都转化为20了吗?”但仔细看,会发现,应该先转换,在判断是否存过对应的值,于是我们修改一下,便得到了新版的错误代码。。。
#include<iostream>
#include<cstring>
using namespace std;
long long f[25][25][25];
long long w(int a, int b, int c) {
if (a <= 0 || b <= 0 || c <= 0)return 1;
if (a > 20 || b > 20 || c > 20)return w(20, 20, 20);
if (f[a][b][c] != -1) return f[a][b][c];
return f[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);
}
int main() {
memset(f, -1, sizeof(f));
long long a, b, c;
while (cin >> a >> b >> c) {
if (a == b && b == c && a == -1) break;
cout << "w("<<a<<", " <<b<<", " <<c<<") = " << w(a, b, c) << "\n";
}
return 0;
}
这次问题又出在哪呢?没错就是函数体,虽然主函数中定义的是long long,但在函数体里使用的仍然是int,因为鼠鼠刚开始以为int就够了,后面发现int不够,便改成long long但没想到还有漏网之鱼,大家写的时候也一定要注意了
接下来就可以贴正确代码哩
#include<iostream>
#include<cstring>
using namespace std;
long long f[25][25][25];
long long w(long long a, long long b, long long c) {
if (a <= 0 || b <= 0 || c <= 0)return 1;
if (a > 20 || b > 20 || c > 20)return w(20, 20, 20);
if (f[a][b][c] != -1) return f[a][b][c];
return f[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);
}
int main() {
memset(f, -1, sizeof(f));
long long a, b, c;
while (cin >> a >> b >> c) {
if (a == b && b == c && a == -1) break;
cout << "w("<<a<<", " <<b<<", " <<c<<") = " << w(a, b, c) << "\n";
}
return 0;
}
如果有帮助还请点个赞,有问题的话可以评论捏