zoukankan      html  css  js  c++  java
  • [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-4cdot cdot cdot 1cdot cdot cdot x+1cdot cdot cdot ncdot cdot cdot y+4,y+2,y$

    例如x=3,y=8,n=10,则一定如下:

    $3,1,2,4,x ,x ,7,9,10,8$

    4,x,x,7相当于求1,x,x,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 }
  • 相关阅读:
    第五届河南省大学生程序设计竞赛 :最强DE战斗力(大数乘法)
    zzuli2455: 最大增区间(一)
    zzuli2455: 最大增区间(一)
    zzuli2424: 越靠近,越幸运(dfs)
    菜根谭#31
    菜根谭#30
    菜根谭#29
    菜根谭#28
    菜根谭#27
    菜根谭#26
  • 原文地址:https://www.cnblogs.com/sainsist/p/11372914.html
Copyright © 2011-2022 走看看