第七篇 算法很美之递归,剪枝,DFS,回溯等问题
题目1 : Exam29_Tile
描述
有一长度为N(1<=N<=1000)的地板,给定两种不同瓷砖:一种长度为1,另一种长度为2,数目不限。
要将这个长度为N的地板铺满,一共有多少种不同的铺法?
为了防止溢出,请将结果Mod 1000000007
输入
一个整数N。(1 <= N <= 1000)
输出
铺法的数量Mod 1000000007
样例输入
3
样例输出
3
附本人AC代码
#include<stdio.h>
int main()
{
int n,i;
int a[1001];
scanf("%d",&n);
a[0]=1;
a[1]=1;
for(i=2;i<=n;i++)
{
a[i]=a[i-1]+a[i-2]; // 从小到大 存储不同长度的种数
a[i]=a[i]%1000000007;
}
printf("%d",a[n]);
return 0;
}
题目2 : Exam30_Change
描述
公园票价为5角。假设每位游客只持有两种币值的货币:5角、1元。
再假设持有5角的有m人,持有1元的有n人。
由于特殊情况,开始的时候,售票员没有零钱可找。
我们想知道这m+n名游客以什么样的顺序购票则可以顺利完成购票过程。
显然,m < n的时候,无论如何都不能完成; m>=n的时候,有些情况也不行。
比如,第一个购票的乘客就持有1元。
请计算出这m+n名游客所有可能顺利完成购票的不同情况的组合数目。
注意:只关心5角和1元交替出现的次序的不同排列,持有同样币值的两名游客交换位置并不算做一种新的情况来计数。
输入
一行:整数m和n,空格隔开。(m+n<=20)
输出
组合数目
样例输入
5 5
样例输出
42
附本人AC代码
#include<stdio.h>
// 递归 0.5少一张 或者1少一张
int fun(int m,int n)
{
if(m<n)
return 0;
if(n==0)
return 1;
return fun(m-1,n)+fun(m,n-1);
}
int main()
{
int i,s;
int m,n; /// m 0.5 || n 1
scanf("%d %d",&m,&n);
if(m<n)
{
printf("0\n");
return 0;
}
s=fun(m,n);
printf("%d\n",s);
return 0;
}
题目3 : Exam32_Cow
描述
假设农场中成熟的母牛每年只会生一头小母牛,并且永远不会死。第一年农场有1只成熟的牛,从第二年开始,母牛开始生小母牛。每只小母牛3年之后 成熟又可以生小母牛。
给定整数N,返回N年后牛的数量
为防止溢出,请将结果结果mod 1000000007
输入
N(1<=N<=1000)
输出
N年后牛的数量 mod 1000000007
样例输入
6
样例输出
9
附本人AC代码
#include<stdio.h>
// 找规律 后面得出 a[i]=a[i-1]+a[i-3]
int main()
{
int n,s,i,a[1001];
scanf("%d",&n);
for(i=1;i<=n;i++)
{
if(i<5)
a[i]=i;
else
a[i]=a[i-1]%1000000007+a[i-3]%1000000007;
}
printf("%d",a[n]%1000000007);
return 0;
}