題意
給你一個數字 n (2<=n<=1e5),代表長度爲 n 的排列(第 i 個數字爲 ),並且給你兩張正整數 x, y,問滿足下麪條件的排列有多少種:
- 對於所有的 ,
真題解:
假題解:
首先分析一個很經典的問題,當有多少種排列
通過打表很容易得到遞推式, dp(n) = dp(n-1) + dp(n-3);
但是分析也是很重要的,
考慮長度爲 n 的排列,最後一位是 n, 則倒數第二位只能是 n-1 或者 n-2
當 的時候 ,dp(n) = dp(n-1)
當 的時候 ,則倒數第三位只能放 n-1 ,因爲如果 n-1 只能放在 n-2 和 n-3 之間,這時候不放 n-1 ,後面依次放下去一定不合法, 因爲已經放了 n-1,n-2,n ,倒數第四位一定是 n-3,原因上面已經說明,則 dp(n) = dp(n-3)
兩種策略合起來,則
但是這個題目如何分析呢,因爲首位是 x,末尾是 y,不妨設x<y並且 x!=1 , y!=n(請注意)
因爲第一位爲 x,我第二位能放 x-2,x-1,x+1,x+2 ,有這四種情況
分析:
-
,則 一定要爲 x-1 ,不然比 x 小的沒法放了,現在已經有了 ,仔細分析發現只能減少了,不能再增加了,所以這種策略失敗
-
,如果一直增加,肯定只會增加2(增加1上面證明了是失敗了策略),然後再來分析能不能減少,考慮最簡單的只有也就是 x,x+2, 減少只能放 x+1, 然後現在要麼減少要麼增加,肯定不能又把 1放好又把 y 放好,則這種策略也失敗了
-
,和第一種方案類似,不能全部放完,失敗。
-
,由於前面幾次的分析,發現必須得把1放好,也就是一直放到最小,切每次減2,相當於 x,x-2,x-4,…,1(偶數的話直接2在1), 然後在看x的是奇數偶數,,舉個例子
-
-
對於y同理,然後發現排列可以看做 首位是 x+1, 末位是 y-1 ,其他數爲 ,同時減去x的話,不是我們上面那個dp 的結論嗎
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#define LL long long
using namespace std;
const int INF=1e9;
const int N=1e5+5;
const int mod=998244353;
int dp[N];
int main()
{
dp[1]=1;dp[2]=1;dp[3]=1;
for(int i=4;i<N;i++)
dp[i]=(dp[i-1]+dp[i-3])%mod;
int t;cin>>t;
while(t--){
int n,x,y;
scanf("%d%d%d",&n,&x,&y);
if(x!=1)x=x+1;
if(y!=n)y=y-1;
printf("%d\n",dp[y-x+1]);
}
}