递归1
T1 圆环套圆环
题目:
一个有趣的圆环套圆环函数被定义如下:
G(n)=n-G(G(n-1)) (n是正整数)
G(0)=0
请你计算出圆环函数的值。
输入
一个非负整数n,n<=200。
输出
一个正整数,即G(n)。
输入样例
3
输出样例
2
思路:
这道题我一开始的想法很简单,就是直接递归题目中给的函数就行了,但是后来发现会TLE,但又想不通,然后我们班一个神犇跟我说要用记忆化搜索,但记忆化搜索又是神马东西呢,下一题再一块讲了。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,h,s[210];
int g(int a)
{
if(a==0)
return 0;
if(a==1)
return 1;
if(s[a]!=0)
return s[a];
s[a]=a-g(g(a-1));
return s[a];
}
int main()
{
cin>>n;
cout<<g(n);
return 0;
}
T2 桐桐的递归函数
题目:
桐桐经常找一些很有趣的数学书来阅读以增长自己的数学知识。一天,他偶然发现一个递归函数w(a,b,c)有以下性质:
如果a≤0或b≤0或c≤0则返回1;
如果a>20或b>20或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,-1,-1结束。
保证输入的数在-9223372036854775808~9223372036854775807之间并且是整数(long long 能存)。
输出
若干行
格式:
w(a,_b,c)=_你的输出 (_代表空格)
输入样例
1 1 1
2 2 2
10 4 6
50 50 50
-1 7 18
-1 -1 -1
输出样例
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
思路:
和T1思路类似,就是以题目给出的递归条件和方法进行递归,直到结束为止,但是如果直接递归,那么连样例都过不了。这时候就要用到记忆化搜索了。
记忆化搜索:用数组将曾经求过的数据存起来,下次如果再出现则直接调用,就不需要重复算了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ULL;
ULL s[30][30][30];
ULL dg(ULL a,ULL b,ULL c)
{
if(a<=0||b<=0||c<=0)
return 1;
else if(a>20||b>20||c>20)
return dg(20,20,20);
if(s[a][b][c]!=0)
return s[a][b][c];
else if(a<b&&b<c)
s[a][b][c]=dg(a,b,c-1)+dg(a,b-1,c-1)-dg(a,b-1,c);
else
s[a][b][c]=dg(a-1,b,c)+dg(a-1,b-1,c)+dg(a-1,b,c-1)-dg(a-1,b-1,c-1);
return s[a][b][c];
}
int main()
{
ULL k1,k2,k3;
while(1)
{
cin>>k1>>k2>>k3;
if(k1==-1&&k2==-1&&k3==-1)
break;
cout<<"w("<<k1<<", "<<k2<<", "<<k3<<") = "<<dg(k1,k2,k3)<<endl;
}
return 0;
}