这题吧。。。
怎么说呢。。。。
题意是给你一个N,求1到N的排列的数目
排列有两个要求
1:必须以1为开头
2:相邻两个数之差不得大于2
3:没了
-------------------以下是思路----------
首先是观察
手写了长度从1到7的排列
(我写了四遍我会说
每次N的增加就是从1~(N-1)的排列中插入一个N
而N插入的位置只和(n-1)还有(n-2)的位置有关
显而易见,可以吧一个符合要求的排列按照最大数和次大叔分为四类
(用A来表示最大数,B来表示次大数,O表示其他数
1:OAB
2:OBA
3:OABO(或者OBAO,这两种是等价的 (想一想,为什么
4:BOA
然后还有转化的关系 (过程不再给出
1->4或3
2->1或2
3->3
4->2
再然后就是状态转移方程了
dp[0][i]=dp[1][i-1];
dp[1][i]=dp[1][i-1]+dp[3][i-1];
dp[2][i]=dp[0][i-1]+dp[2][i-1];
dp[3][i]=dp[0][i-1];
以及代码
----------------------------我是代码-----------------------
#include<cstdio>
#include<cstring>
using namespace std;
int dp[4][60];
int main(){
memset(dp,0,sizeof(dp));
dp[1][1]=1;
dp[1][2]=1;
for(int i=3;i<=55;i++){
dp[0][i]=dp[1][i-1];
dp[1][i]=dp[1][i-1]+dp[3][i-1];
dp[2][i]=dp[0][i-1]+dp[2][i-1];
dp[3][i]=dp[0][i-1];
}
int k;
while(~scanf("%d",&k)){
printf("%d\n",dp[0][k]+dp[1][k]+dp[2][k]+dp[3][k]);
}
return 0;
}