[2019杭电多校第五场][hdu6630]permutation 2

题目链接: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]。

扫描二维码关注公众号,回复: 7057565 查看本文章
 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 }

猜你喜欢

转载自www.cnblogs.com/sainsist/p/11372914.html