题目描述:
小明十分聪明,而且十分擅长排列计算。
有一天小明心血来潮想考考你,他给了你一个正整数n,序列1,2,3,4,5......n满足以下情况的排列:
1、第一个数必须是1
2、相邻两个数之差不大于2
你的任务是给出排列的种数。
输入描述:
多组数据。每组数据中输入一个正整数n(n<=55).
输出描述:
输出种数。
样例输入:
4
样例输出:
4
解题:递推类型的规律题
设数列为A,A1、A2、A3...表示第1、2、3...位数
A1 = 1是确定的。则A2要么等于2,要么等于3。
(1)如果A2 = 2,则A2~An的排序数等于A1~A(n-1)的排列数,dp[n-1]
(2)如果A2 = 3
A3 = 2,A4 = 4必然成立,则A4~An的排序数 等于 A1~A(n-3)的排列数,dp[n-3]
A3 = 4
1)A4 = 2,A5最小为5,不成立
2)A4 = 5,还有一个2没放进去,然而能和2相邻的只有1,3,4,都已经出现过,不成立
A3 = 5 ,可以奇数递增再偶数递减回来,比如1,3,5,7,9,10,8,6,4,2。无论n是奇数还是偶数,都不能有一点差错,所以是1种。
dp[n] = dp[n-3] + dp[n-1] + 1;
n=1,dp[1]=1
n=2,dp[2]=1 12
n=3,dp[3]=2 123,132
n=4,dp[4]=4 1234,1243,1324,1342
n=5,dp[5]=6 12345,12354,12435,12453,13425,13542
......
#include<stdio.h> int dp[66]; int n; int main() { dp[1]=1; dp[2]=1; dp[3]=2; dp[4]=4; dp[5]=6; for(int i=6;i<=60;i++) dp[i]=dp[i-3]+dp[i-1]+1; while(scanf("%d",&n)!=EOF) printf("%d ",dp[n]); return 0; }