这题吧。。。
怎么说呢。。。。
题意是给你一个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; }