Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9133 | Accepted: 4740 |
Description
Input
Output
Sample Input
2 8 12 -1
Sample Output
3 153 2131
题意:一个3 * n的矩阵,用1 * 2的矩阵拼凑而成,问有多少种拼法
思路:递推,先假设输入的数字模2变成一个单位 1 (因为奇数是不可以使用的,拼不满)。
有木块拼满一单位有3种可能,其他有2种可能,ans[i]表示当前的解:
1.在此处放一单位的积木。等于 3 * ans[i-1];(就是此处一单位积木可以有三种变化形式)
2.与前面相连接。连接的方案有 2 * (ans[i-2] + ans[i-3] +......+ ans[0]);(因为任意两个单位的在一起还有两种变化)
因此有:ans[i] = 3 * ans[i-1] + 2 * (ans[i-2] + ans[i-3] +......+ ans[0]);--------(1)
理解到这里应该就差不多了,当然也可以再化简为 ans[i] = 4 * ans[i-1] - ans[i-2];-----------(2)
另外还要注意几点:1.奇数单位不能拼满。 2. 0的时候输出1(可能是出题者的假设,他忘了改了)
第二种递归方法是用式子 2 写出来的
#include<stdio.h> int ans[35]; int main() { ans[0]=1;ans[1]=3; for(int i=2;i<=15;i++){ ans[i]=3*ans[i-1]; for(int j=0;j<i-1;j++){ ans[i]+=2*ans[j]; } } int n; while(scanf("%d",&n),n!=-1) { if(n%2!=0) printf("0\n"); else printf("%d\n",ans[n/2]); } return 0; }
#include<stdio.h> int ans[18]; void deal(int x) { if(x==1||x==0) return ; deal(x-1); ans[x]=4*ans[x-1]-ans[x-2]; } int main() { ans[0]=1;ans[1]=3; deal(16); int n; while(scanf("%d",&n),n!=-1) { if(n%2!=0) printf("0\n"); else printf("%d\n",ans[n/2]); } return 0; }