zoukankan      html  css  js  c++  java
  • hdu多校第五场1007 (hdu6630) permutation 2 dp

    题意:

    给你n个数,求如下限制条件下的排列数:1,第一位必须是x,2,最后一位必须是y,3,相邻两位之差小于等于2

    题解:

    如果x<y,那么考虑把整个数列翻转过来,减少讨论分支。

    设dp[n]为限制1和n在两边,相邻的数之差小于等于2的排列方案。

    dp[0]=1  dp[1]=1  dp[2]=2  dp[3]=3

    如果x==1 y==n 直接用公式dp[i]=dp[i-1]+dp[i-3]求解,将i代入为(y-x)-1,即xy之间的元素数。

    如果x!=1 或者y!=n,假如对于12个的情况,x=4,y=9

    那么,1,2,3,5与8,10,11,12必然挤在两边,

    以这样的形式:4,2,1,3,5......8,10,12,11,9

    因为必须把x+1,y-1放在6,7的两边,将i带入为(y-1)-(x+1)-1,答案就是dp[2]

    两边的数只有一边不靠边则分类讨论。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int M = 1e5 + 5;
    const LL mod = 998244353;
    const LL lINF = 0x3f3f3f3f3f3f3f3f;
    LL dp[M];
    int l, r, n;
    int t;
    int main()
    {
        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        for (int i = 4; i <= M - 2; i++)
        {
            dp[i] = (dp[i - 1] + dp[i - 3])%mod;
        }
        scanf("%d", &t);
        while (t--)
        {
            scanf("%d%d%d", &n, &l, &r);
            if (l > r)
                swap(l, r);
            if (l != 1)
                l++;
            if (r != n)
                r--;
            if (l > r)
                printf("0
    ");
            else if (l == r)
                printf("1
    ");
            else
                printf("%lld
    ", dp[r - l - 1]);
        }
    }
  • 相关阅读:
    Nginx Record
    Go 查找元素
    博客转移公告
    模板库
    模板库
    【BZOJ2276】Temperature
    【BZOJ3524】Couriers
    【BZOJ4458】GTY的OJ
    AtCoder Grand Contest 007
    Editing 2011-2012 ACM-ICPC Northeastern European Regional Contest (NEERC 11)
  • 原文地址:https://www.cnblogs.com/isakovsky/p/11306281.html
Copyright © 2011-2022 走看看