2019hdu暑假多校第五场1007 permutation 2 HDU - 6630
You are given three positive integers N,x,y.
Please calculate how many permutations of 1∼N satisfies the following conditions (We denote the i-th number of a permutation by pi):
1. p1=x
2. pN=y
3. for all 1≤i<N, |pi−pi+1|≤2
题意:
给出N,x,y。问以x为开头,y为结尾,且相邻2个数之差不超过2的1~N的排列方案有多少种。
思路:
对于ai,下一位可以是ai-1,ai-2,ai+1,ai+2。当ai变小时,路径是固定的(只能隔着跳去变小,否则是无法变回ai+1),而且必然是先把小的数是塞进序列中,然后在回到a+1,对于剩下的数进行排列,否则,小的数是无法塞进序列的。
那么同理,当y!=n时,序列从后往前应该是先变大在变小到y-1.
那么问题也就是对于x+1~y-1满足条件的排列有多少种。
对于第i位的ai :第i+1位可以位ai+1或ai+2.
1:当第i+1位为ai+1时,继续往下讨论即可;
2:当第i+1位为ai+2时,第i+2位必然是ai+1,第i+3位必然是ai+3。否则如果以后在某一位再想回到ai+1,就走死了,回来了却无法回去。
由上可知,第i位可以由第i-1和第i-3位到达。此处用到斐波那契,f[i]=f[i-1]+f[i-3](f[1]=f[2]=f[3]=1)。
综上:
1:x==1&&y==n.....ans=f[n];
2:x==1&&y!=n.......ans=f[y-1];
3:x!=1&&y==n.......ans=f[n-x];
4:x!=1&&y!=n......ans=f[y-x-1];
#include<bits/stdc++.h> using namespace std; #define ll long long const ll mod = 998244353; ll n,x,y; ll a[100005]; void fun(){ for(ll i=4;i<=100000;i++) { a[i]=(a[i-1]+a[i-3])%mod; } } int main() { int t; ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); a[1]=1;a[2]=1;a[3]=1; fun(); cin>>t; while(t--) { cin>>n>>x>>y; if(x==1&&y==n) cout<<a[n]<<endl; else if(x==1) cout<<a[y-1]<<endl; else if(y==n) cout<<a[n-x]<<endl; else cout<<a[y-x-1]<<endl; } return 0; }