洛谷 P1464 Function

在这里插入图片描述

在这里插入图片描述
先按照题意把递归的内容写出来,然后把每次0~20以内的答案记录下来,下一次递归时如果rpt(x,y,z)有记录就直接输出,能省去大量时间。

注意:输入中有负数,因此一开始的判断语句不能只写if(rpt[x][y][z]),因为不能访问数组负数下标,应加一个特判。

记忆化搜索:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll rpt[25][25][25];//全局变量数组自动置零
ll w(ll a, ll b, ll c)//用三维数组记录递归得到的值,减少递归次数
{
 if (a <= 0 || b <= 0 || c <= 0) return 1;
 else if (rpt[a][b][c] != 0)return rpt[a][b][c];//不能写在第一句,如果下标为负,数组会越界
 //把数组初始化成不可能达到的值,判断条件就是不等于这个不可能达到的值
 else if (a > 20 || b > 20 || c > 20)rpt[a][b][c] = w(20, 20, 20);
 else if (a < b&&b < c)rpt[a][b][c] = w(a, b, c - 1) + w(a, b, c - 1) - w(a, b - 1, c);
 else rpt[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 rpt[a][b][c];
}
int main()
{
 ll a, b, c;
 while (cin >> a >> b >> c)
 {
  if (a == -1 && b == -1 && c == -1)break;
  cout << "w(" << a << ", " << b << ", " << c << ") = ";
  if (a > 20)a = 21;if (b > 20)b = 21;if (c > 20)c = 21;//防止数组越界
  cout << w(a, b, c) << endl;
 }
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值