Function(洛谷p1464)C++实现

题目链接: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;
}

如果有帮助还请点个赞,有问题的话可以评论捏

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值