【题目链接】
OpenJudge NOI 2.6 1944:吃糖果
注:ybt 1193:吃糖果 页面打不开,可以在OpenJudge做该题。
【题目考点】
1. 递推/递归
2. 搜索
【解题思路】
解法1. 递推
- 递推状态:a[i]:吃i个巧克力的方案数
- 初始状态:
- 要吃1块巧克力,方案数为1:
a[1] = 1
。 - 要吃2块巧克力,方案数为2:
a[2] = 2
。
- 要吃1块巧克力,方案数为1:
- 递推关系:
要想吃i个巧克力,先考虑第1天吃几块- 如果第1天吃1块巧克力,接下来吃i-1块巧克力的方案数为
a[i-1]
,因此这种情况下的方案数为:a[i-1]
。 - 如果第1天吃2块巧克力,接下来吃i-1块巧克力的方案数为
a[i-2]
,因此这种情况下的方案数为:a[i-2]
。 - 因此吃i个巧克力的方案数为
a[i] = a[i-1] + a[i-2]
- 如果第1天吃1块巧克力,接下来吃i-1块巧克力的方案数为
实际就是一个求斐波那契数列第n项的问题。
解法2:递归
n最大为20,使用普通递归或记忆化递归均可。
解法3:深搜
问题规模不大,用深搜也可以解该题
【题解代码】
解法1:递推
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, a[25];
cin >> n;
a[1] = 1, a[2] = 2;
for(int i = 3; i <= n; ++i)
a[i] = a[i-1] + a[i-2];
cout << a[n];
return 0;
}
解法2:递归
- 一般递归
#include <bits/stdc++.h>
using namespace std;
int solve(int k)//返回吃k个巧克力的方案数
{
if(k <= 2)
return k;
return solve(k-1) + solve(k-2);
}
int main()
{
int n;
cin >> n;
cout << solve(n);
return 0;
}
- 记忆化递归
#include <bits/stdc++.h>
using namespace std;
int a[25];//a[i]:吃i个巧克力的方案数
int solve(int k)//返回吃k个巧克力的方案数
{
if(a[k] > 0)
return a[k];
if(k <= 2)
return k;
return a[k] = solve(k-1) + solve(k-2);
}
int main()
{
int n;
cin >> n;
cout << solve(n);
return 0;
}
解法3:深搜
#include <bits/stdc++.h>
using namespace std;
int ans;
void dfs(int a)//要吃a颗巧克力 统方案径数
{
for(int i = 1; i <= 2; ++i)//这一次吃i个巧克力
{
if(a-i == 0)
ans++;//方案数加1
else if(a-i > 0)
dfs(a-i);//看下一次吃几个
}
}
int main()
{
int n;
cin >> n;
dfs(n);
cout << ans;
return 0;
}