杭电1331 Function Run Fun

杭电1331 Function Run Fun

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8049 Accepted Submission(s): 3625

Problem Description

我们都喜欢递归!我们不是吗?
考虑一个三参数递归函数w(a,b,c):

如果a<=0或b<=0或c<=0,则w(a,b,c)返回:
1

如果a>20或b>20或c>20,则w(a,b,c)返回:
w(20,20,20)

如果a<b和b<c,则w(a,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的中等值(例如,a=15,b=15,c=15),由于大量递归,程序运行需要数小时。

Input

程序的输入将是一系列整数三元组,每行一个,直到文件结束标志-1-1-1。使用上述技术,您可以高效地计算w(a,b,c)并打印结果

Output

打印每个三元组的w(a,b,c)值。

Sample Input

1 1 1
2 2 2
10 4 6
50 50 50
-1 7 18
-1 -1 -1

Sample Output

w(1, 1, 1) = 2
w(2, 2, 2) = 4
w(10, 4, 6) = 523
w(50, 50, 50) = 1048576
w(-1, 7, 18) = 1

分析:

这是一道ACM的题目,意味着它可能会超时,总所周知:ACM的时间短的有时甚至容不下三重循环,所以,想要用递归的同学就会发现程序超时,并不能快乐的AC。所以我们采取用空间换时间的方法来缩短运行时间,废话少说,上代码:



 
using namespace std;

int f[25][25][25];
//有题目可知我们真正需要计算的只有a,b,c,0到20之间的数,
//所以我们先要用蛮力法穷举这8000种情况。
//我们在这里定义一个全局变量的数组,目的是将前20位计算结果进行存储,
//方便后面的输出。

void w(int a, int b, int c)
{
	if (a <= 0 || b <= 0 || c <= 0)
	{
		f[a][b][c] = 1;
		//这一步好像和main函数重复了,但这不是冗余,这是为数组赋初值
		//否则输出的结果会为0,因为没有为数组赋初值值
	}
	 else if (a < b && b < c)
	{
		f[a][b][c] = 
		f[a][b][c - 1] + f[a][b - 1][c - 1] - f[a][b - 1][c];//这些看仔细了,别抄错了。
	}
	else
	{
		f[a][b][c] = 
		f[a - 1][b][c] + f[a - 1][b - 1][c] + f[a - 1][b][c - 1]
		 - f[a - 1][b - 1][c - 1];
	}

}

int main()
{
	int a, b, c;
	int i, j, k;
	for (i = 0; i < 21; i++)
	{
		for (j = 0; j < 21;j++)
		{
			for (k = 0; k < 21; k++)
			{
				w(i, j, k);
				//在这里调用w函数,进行穷举
			}
		}
	}
	while (cin >> a >> b >> c)
	//这个循环的目的就是进行输出
	{
		if (a == -1 && b == -1 && c == -1)
		{
			break;
		}
		if (a <= 0 || b <= 0 || c <= 0)
		{
			cout << "w(" << a << ", " << b << ", " << c << ") = " 
			<< 1 << endl;
			continue;
		}
		if (a > 20 || b > 20 || c > 20)
		{
			cout << "w(" << a << ", " << b << ", " << c << ") = " 
			<< f[20][20][20] << endl;
			continue;
		}
		cout << "w(" << a << ", " << b << ", " << c << ") = "
		 << f[a][b][c] << endl;
	}

	return 0;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值