2019hdu暑假多校第五场1007 permutation 2 HDU - 6630

You are given three positive integers N,x,y.
Please calculate how many permutations of 1N satisfies the following conditions (We denote the i-th number of a permutation by pi):

1. p1=x

2. pN=y

3. for all 1i<N|pipi+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;
 } 

 

posted @ 2019-08-06 11:31  一只球球  阅读(186)  评论(0编辑  收藏  举报