题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6630
题意为求出1-n,n个数的全排列中有多少种方案满足第一位为x,第n位为y,且相邻数字绝对值之差不超过2。
我们可以预处理d数组,定义d[i]表示1-i个数的全排列中以1为第一位,i为第i位且相邻数字绝对值之差不超过2的方案数。
则第i位为i,可以由第i-1位转移,表示i位与i-1位数字绝对值之差为1,则$d[i]+=d[i-1]$,也可以由第i-3位转移,表示第i-1位为i-2,第i-2位为i-1,表示i位与i-1位数字绝对值之差为2。则$d[i]+=d[i-3]$
$d[i]=d[i-3]+d[i-1]$
然后考虑第1位为x,第n位为y的情况。
则从前往后看一定是x先递减到1再递增,从后往前看一定是y先递增到再递减。
$x,x-2,x-4\cdot \cdot \cdot 1\cdot \cdot \cdot x+1\cdot \cdot \cdot n\cdot \cdot \cdot y+4,y+2,y$
例如x=3,y=8,n=10,则一定如下:
$3,1,2,x,x ,x ,x,9,10,8$
相当于求 x =1,y=4,n=4。也就是预处理出来的d[4]。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 using namespace std; 7 typedef long long ll; 8 const int maxn = 1e5 + 10; 9 const ll mod = 998244353; 10 ll d[maxn]; 11 void init() { 12 d[1] = d[2] = d[3] = 1; 13 for (int i = 4; i < maxn - 2; i++) 14 d[i] = (d[i - 1] + d[i - 3]) % mod; 15 } 16 int main() { 17 init(); 18 int t; 19 scanf("%d", &t); 20 while (t--) { 21 int n, x, y; 22 cin >> n >> x >> y; 23 if (x == 1 && y == n) 24 cout << d[n] << endl; 25 else if (x == 1 || y == n) 26 cout << d[y - x] << endl; 27 else 28 cout << d[y - x - 1] << endl; 29 } 30 }
原文地址:https://www.cnblogs.com/sainsist/p/11372914.html
时间: 2024-11-05 20:23:44