NYOJ469 - 擅长排列的小明 II - (dp)

题目描述:

小明十分聪明,而且十分擅长排列计算。

有一天小明心血来潮想考考你,他给了你一个正整数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\n",dp[n]);
    return 0;
}

 

 
posted @ 2019-05-23 00:45  守林鸟  阅读(197)  评论(0编辑  收藏  举报