【记忆化搜索】P1464 Function

https://www.luogu.com.cn/problem/P1464

考点:记忆化搜索、递归、map

在这里插入图片描述

题意:
按照题目要求写递归函数。

解法:
在函数开始时查看哈希表中是否已经有答案记录,如果有就直接返回。如果没有答案,则正常执行,返回前把答案添加到哈希表,记忆化搜索可以大幅度提高递归的效率。
实际上是水题,但是我卡了挺长时间的,原因是对STL的map不熟悉。我自定义了一个三元组类用来表示3个参数,是类似pair的数据结构。

struct TT {
	ll a,b,c;
	TT(ll x, ll y, ll z) {
		a=x; b=y; c=z;
	}

	bool operator<(const TT &t) const { 
		if (a != t.a) return a < t.a;
		if (b != t.b) return b < t.b;
		return c < t.c;
	}
};

对于自定义类作为map的键的时候,必须重载小于运算符,而且不能乱写,我一开始只对比了a的值,导致map索引失败。正确做法应该是依次比较abc的值。

完整代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct TT {
	ll a,b,c;
	TT(ll x, ll y, ll z) {
		a=x; b=y; c=z;
	}

	bool operator<(const TT &t) const { 
		if (a != t.a) return a < t.a;
		if (b != t.b) return b < t.b;
		return c < t.c;
	}
};
map<TT, ll> M;
ll w(ll a, ll b, ll c) {
	if (M.find({a,b,c}) != M.end()) return M[{a,b,c}];
	if (a <= 0 || b <= 0 || c <= 0) {
		M[{a,b,c}] = 1;
		return 1;
	}
	if (a > 20 || b > 20 || c > 20) {
		ll res = w(20, 20, 20);
		M[{a,b,c}] = res;
		return res;
	}
	if (a < b && b < c) {
		ll res = w(a,b,c-1) + w(a,b-1,c-1) - w(a,b-1,c);
		M[{a,b,c}] = res;
		return res;
	}
	ll res = w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1);
	M[{a,b,c}] = res;
	return res;
}
int main() {
	ll 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;
}
发布了105 篇原创文章 · 获赞 24 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Kwansy/article/details/103570287