问题描述
有一长度为N(1<=N<=10)的地板,给定两种不同瓷砖:一种长度为1,另一种长度为2,数目不限。要将这个长度为N的地板铺满,一共有多少种不同的铺法?
例如,长度为4的地面一共有如下5种铺法:
4=1+1+1+1
4=2+1+1
4=1+2+1
4=1+1+2
4=2+2
编程用递归的方法求解上述问题。
例如,长度为4的地面一共有如下5种铺法:
4=1+1+1+1
4=2+1+1
4=1+2+1
4=1+1+2
4=2+2
编程用递归的方法求解上述问题。
输入格式
只有一个数N,代表地板的长度
输出格式
输出一个数,代表所有不同的瓷砖铺放方法的总数
样例输入
4
样例输出
5
思路:
1 直接递归,因为N是k个1和k1个2的组合(k,k1不确定),我们递归的时候,只要设置出口为i==N即可
#include <stdio.h> int result; void GetResult(int i,int n) { if (i == n) { result++; return; } if (i + 1 <= n) { GetResult(i + 1,n); } if (i + 2 <= n) { GetResult(i + 2,n); } } int main() { int N; scanf("%d",&N); GetResult(0,N); printf("%d ",result); return 0; }
2 N=2K+K1,用floor存放瓷砖特定的组合,然后进行无重复全排列(去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换),并用sum计数
#include <stdio.h> short sum; int floor[10];//最多10块不同的瓷砖铺成地板 void swap(int i,int k)//交换 { floor[i] = floor[k] + floor[i] - (floor[k] = floor[i]); } int IsSwap(int i,int t)//判断重复 { int k; for(k=i;k<t;k++) if(floor[k] == floor[t]) return 0; return 1; } void Permutation(int i,int j) { int t; if(i == j) { sum ++; } for(t=i;t<j;t++) { if(IsSwap(i,t))//没有重复 { swap(i,t); Permutation(i+1,j); swap(i,t);//一定要再交换回来 } } } int main() { int N,i,j; scanf("%d",&N); sum = 1;//瓷砖全为1 j = 0; for(i=1;i<=N/2;i++) { for(j=0;j<i;j++) floor[j]=2; for(j=i;j<N-i;j++)//注意:j<N-2i+i=N-i floor[j]=1; Permutation(0,j);//对floor的前j个数做去重复全排列 } printf("%hd ",sum); return 0; }