洛谷P1464—Function

传送门

作为一个蒟蒻,递归是搞不懂的,这辈子都搞不懂的

正题开始

作为一个已经将“递归”二字刻在脑门上的递归题,明显是要用递归解决。这不废话吗

递归的规则已经告诉我们了,我们直接照着规则来就行。

递归规则:

  • 如果(a le 0) (or) (b le 0) (or) (c le 0)就返回值(1).

  • 如果(a>20) (or) (b>20) (or) (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))

(1)条和第(2)条规则很明显是一个边界,每条规则的优先级是从上到下,这个优先级不能错。

还有那只要长了眼就能看到的提示:记忆化搜索。

那记忆化搜索又是怎么一回事呢?

敲黑板

记忆化搜索(Memory search)简称记忆化,是一种用于保留 每次搜索的结果动态规划的某一进程的一种方式。

记忆化搜索

举一个很好理解的栗子

走迷宫

在走迷宫时,不通的路一般我们会打上一个记号,以免重复的走这条路,达到节省时间的效果。

显然是一个空间换时间

因为你需要用空间来存储记号

这个题也一样,在算已经算过的数据时只需要调用之前运行过的结果就可以了。

而在算没算过的数据时,算完要将结果保存下来,以备时需。

记忆化核心代码:

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(function[a][b][c]!=-1)//判断有没有算过
	    return function[a][b][c];//算过就直接返回结果
	
	if(a<b&&b<c)//规则3
	{
		function[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);//记忆化
		return function[a][b][c];
	}
        //前三个规则都不是
	function[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);//记忆化
	return function[a][b][c];
}

谢谢观看

完结撒花 (。・∀・)ノ❤❤❤❤❤❤

我要拿金牌!
原文地址:https://www.cnblogs.com/jerrywang-blogs/p/P1464.html