HDU-#2044-2050 递推求解专题
来源:互联网 发布:wav播放软件 编辑:程序博客网 时间:2024/05/19 06:18
HDU的#2044-2050是递推专题训练,递推关系在数学专题中是很重要的一部分,也是规律性和技巧性很强的一部分。下面给出这个专题的解题报告如下:
专题来源:【HDU递推求解专题训练题】
#2044:一只小蜜蜂...
解题思路:直接递推可以发现,从1开始到每一个点的走法为:1 ,2,3,5,8....这时候很清晰的数列出现在我们面前,那就是斐波那契数列。而问题是要求给出起点到终点的走法,而不是1。但是我们反过来想想,从任何点开始走与从1开始走到他们之间差值那个点的结果是一致的。因此该问题只是斐波那契数列的变形,将a,b的差值作为n即可得到,详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2044
code:
#include <iostream>#include <cstdio>using namespace std;#define ll __int64const int MAXN = 50+10;int n,a,b;ll f[MAXN];int main(){ f[0]=1;f[1]=1; for(int i=2;i<MAXN;i++) f[i]=f[i-1]+f[i-2]; scanf("%d",&n); while(n--){ scanf("%d%d",&a,&b); printf("%I64d\n",f[b-a]); } return 0;}
#2045:不容易系列之(3)—— LELE的RPG难题
解题思路:找不到好的思路时,我们先枚举结果,可以得到:f[1]=3,f[2]=6,f[3]=6,f[4]=18,f[5]=30....,根据枚举的数列可以推导出该递推公式:f[i]=f[i-1]+2*f[i-2],这里数据量不大时可以直接枚举找下规律,要注意边界为:f[1]=3,f[2]=6,f[3]=6。注意数据范围,用__int64来存。详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2045
code:
#include <iostream>#include <cstdio>using namespace std;#define ll __int64const int MAXN = 50+10;int n;ll f[MAXN];int main(){ f[1]=3;f[2]=6;f[3]=6; for(int i=4;i<MAXN;i++) f[i]=f[i-1]+2*f[i-2]; while(scanf("%d",&n)!=EOF) printf("%I64d\n",f[n]); return 0;}
#2046:骨牌铺方格
解题思路:这是一道经典的题目。首先先考虑最左边一列的铺法,若用一个直接纵向覆盖,则剩下的2*(n-1)方格有f(n-1)种铺法;若用两个横向的覆盖,则剩下的2*(n-2)有f(n-2)种铺法。因此递推可以得到f(n)=f(n-1)+f(n-2),边界f(0)=f(1)=1.恰好就是斐波那契数列,直接就可以求解。不过这里还有一种推法,就是考虑第i列纵向骨牌,则左边的i-1列和右边的n-i列各有f(i-1)和f(n-i)种铺法,根据乘法原理以及去掉重复的和加上遗漏的,可以得到另一种递推式:1、当n为偶数的时候,f(n)=1+f(1)+f(3)+...+f(n-1),其中1为没有纵向的情况;2、当n为奇数的时候,f(n)=f(0)+f(2)+f(4)+...+f(n-1)。边界为:f(0)=f(1)=1。因此这也很好地说明了递推式可能存在多种,这也是它规律性和技巧性很强的原因之一。还有就是不完善的解法可以通过打补丁来修复,不过这需要很强的逻辑和理论。解法详见code哈!
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2046
斐波那契数列 code:
#include <iostream>#include <cstdio>using namespace std;#define ll __int64const int MAXN = 50+10;int n;ll f[MAXN];int main(){ f[0]=1;f[1]=1; for(int i=2;i<MAXN;i++) f[i]=f[i-1]+f[i-2]; while(scanf("%d",&n)!=EOF) printf("%I64d\n",f[n]); return 0;}
另一种code:
#include <iostream>#include <cstdio>using namespace std;#define ll __int64const int MAXN = 50+10;int n;ll f[MAXN];int main(){ f[-1]=1;f[0]=1;f[1]=1; for(int i=2;i<MAXN;i++){ if(i%2==0) for(int j=-1;j<MAXN;j+=2) f[i]+=f[j]; else for(int j=0;j<MAXN;j+=2) f[i]+=f[j]; } while(scanf("%d",&n)!=EOF) printf("%I64d\n",f[n]); return 0;}
#2047:阿牛的EOF牛肉串
解题思路:给长度为n的字符串,由EOF三个字符组成,排除OO相连的情况的有多少种组合。直接找规律递推就行。首先分两种情况:一是当第i位为O的时候,则i-1位只能是E or F,对于剩下n-2的情况为f(n-2),则该递推式为1*2*f[n-2];二是当第i位为E or F的时候,那么n-1位为f(n-1),该情况递推式为2*f[n-1]。综上,该递推式为f[n]=2*(f[n-1]+f[n-2]).详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2047
code:
#include <iostream>#include <cstdio>using namespace std;#define ll __int64const int MAXN = 40+5;int n;ll f[MAXN];int main(){ f[1]=3;f[2]=8; for(int i=3;i<MAXN;i++) f[i]=2*(f[i-1]+f[i-2]); while(scanf("%d",&n)!=EOF) printf("%I64d\n",f[n]); return 0;}
#2048:神、上帝以及老天爷
解题思路:这是一个错排问题。先求解错排的数量,然后除以全排的数量就是答案。对于错排情况:对于第n个人,则他的选取方法为n-1种;若选取第i个人的,此时有两种情况,一是该人选取的是第n个人的,则剩余的就是n-2种错排。第二种是不选取第n个人,则此时剩下的n-1种要错排。综上递推式为:f(n)=(n-1)*(f(n-1)+f(n-2))。详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2048
code:
#include <iostream>#include <cstdio>using namespace std;#define ll __int64const int MAXN = 21;ll c[MAXN],f[MAXN];int t,n;int main(){ c[1]=1; for(int i=2;i<=MAXN;i++) c[i]=c[i-1]*i; f[1]=0;f[2]=1; for(int i=3;i<=MAXN;i++) f[i]=(i-1)*(f[i-1]+f[i-2]); scanf("%d",&t); while(t--){ scanf("%d",&n); printf("%.2lf%%\n",100*(double)f[n]/c[n]); } return 0;}
#2049:不容易系列之(4)——考新郎
解题思路:该题是上题的一种变形的,原则上也是一种错排问题,这里要注意(n-m)个人是正确的排列,此时错排的数量要和这(n-m)个进行组合,即c(n,m)*f(n)。这里就不赘述了,详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2049
code:
#include <iostream>#include <cstdio>using namespace std;#define ll __int64const int MAXN = 21;ll c[MAXN],f[MAXN];int t,n,m;int main(){ c[0]=1;c[1]=1; for(int i=2;i<=MAXN;i++) c[i]=c[i-1]*i; f[0]=0;f[1]=0;f[2]=1; for(int i=3;i<=MAXN;i++) f[i]=(i-1)*(f[i-1]+f[i-2]); scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); printf("%I64d\n",c[n]/c[m]/c[n-m]*f[m]); } return 0;}
#2050:折线分割平面
解题思路:这个题比较经典,这里参见了这篇博客,这里讲的比较详细和清楚,规律性比较强,直接递推就可以出来了,就不赘述了,详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2050
code:
#include <iostream>#include <cstdio>using namespace std;int n,t;int main(){ scanf("%d",&t); while(t--){ scanf("%d",&n); printf("%d\n",2*n*n-n+1); } return 0;}
- HDU-#2044-2050 递推求解专题
- hdu 2044-2050 递推求解专题练习
- HDU 2041--超级楼梯题解(递推求解专题)
- Hdu递推求解专题练习(For Beginner)
- 递推求解专题练习(For Beginner) 【hdu】
- 递推求解专题训练
- 递推求解专题练习(For Beginner) 折线分割平面 HDU 2050
- HDU 递推求解专题练习 2045 2046 2047 2048 2049 2050
- HDU 递推专题
- HDOJ(HDU).2044-2049 递推专题
- HDU 2045 递推求解
- HDU 2047--阿牛的EOF牛肉串(递推求解专题)
- HDU 2050- 折线分割平面 -递推求解
- 递推求解专题练习(For Beginner)
- 递推关系求解(HDU 2047+HDU 2045)
- HDU 2041 超级楼梯(递推求解)
- 递推求解
- 简谈--递推求解
- 串操作应用举例(文本编辑)
- 一元N次多项式的表示及相加
- 使用LaunchPopupListener过滤Input Text with LOV(4)
- jQuery选择器总结
- iOS NSData探秘
- HDU-#2044-2050 递推求解专题
- Task Flow使用指南之六:Reentry
- AC自动机(模板题)hdu2896
- DM642的中断学习
- B - Machine Schedule(二分图匹配——匈牙利算法)
- 根据打开文件句柄查找文件
- Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable
- Task Flow使用指南之七:SavePoints(1)
- 【leetcode】Evaluate Reverse Polish Notation