首页 > 其他分享 >AtCoder Beginner Contest 282 G - Similar Permutation

AtCoder Beginner Contest 282 G - Similar Permutation

时间:2023-01-13 20:44:39浏览次数:77  
标签:AtCoder 排列 Beginner Contest int sum 个数 leq 107

套路题

题意

求有多少个 \(1\) 到 \(n\) 的排列满足恰有 \(k\) 对在排列中相邻的数满足前小于后

\(2 \leq n \leq 500, 0 \leq k \leq (n - 1)\)

思路

f[i][j][k] 表示已经放置了前 i 个数, 放置的第i个数是前i个数中第j大的($ 1\leq\(`j`\)\leq$i),已放置的前i个数形成的所有排列满足恰有 k 对在排列中相邻的数满足前小于后的排列数量。

放置第i+1个数时,第i+1个数是前i+1个数中第j大的,第i个数是严格小于前i个数中第j大的,会为排列增加一对相邻的数满足前小于后,第i个数是大于等于前i个数中第j大的,不会为排列增加一对相邻的数满足前小于后,转移方程为:

\[f_{(i + 1) j k} = \sum_{x = 1}^{j - 1}f_{i x (k-1)} + \sum_{x=j}^{i}f_{ixk} \]

显然,后面的和式可以通过前缀和优化的。

时间复杂度为\(O(n^2k)\)。

G - Similar Permutation

传送门

题意

求\(1\)到\(n\)的排列\(A\) 和 \(B\)的相似度为\(k\)的数量。

相似度计算:\(k = \sum_{i = 2}^{n}[(A_i - A_{i-1})(B_i - B_{i-1}) > 0]\) (\([X] = 1, X 为真,[X] = 0, X为假\))。

\(2 \leq n \leq 100, 0 \leq k \leq (n - 1)\)。

思路

与前一道题相比,这一题只是增加了一维状态。

f[i][a][b][k] 表示排列\(A\),\(B\)已经放置了前 i 个数, 排列\(A\)放置的第i个数在排列\(A\)中是第a大的,排列\(B\)放置的第i个数在排列\(B\)中是第b大的,此时相似度为\(k\)的排列数量。

转移方程为:

\[f_{(i+1)abk} = \sum_{x = 1}^{a - 1}\sum_{y = 1}^{b - 1} f_{ixy(k-1)} + \sum_{x = a}^{i}\sum_{y = b}^{i} f_{ixy(k-1)} + \sum_{x = 1}^{a - 1}\sum_{y = b}^{i} f_{ixyk} + \sum_{x = a}^{i}\sum_{y = 1}^{b - 1} f_{ixyk} \]

和式同样可以使用前缀和来优化。

时间复杂度为\(O(n^4)\)。

代码

int pre[107][107][107], f[107][107][107];
void solve_problem() {
    int n, m, P;

    std::cin >> n >> m >> P;

    auto add = [&](int a, int b) -> int {
        a += b;
        if ( a >= P ) a -= P;
        return a;
    };
    auto sub = [&](int a, int b) -> int {
        a -= b;
        if ( a < 0 ) a += P;
        return a;
    };
    auto sum = [&](int n, int x1, int y1, int x2, int y2) -> int {
        if (n < 0) return 0;
        return add(sub(sub(pre[n][x2][y2], pre[n][x2][y1 - 1]), pre[n][x1 - 1][y2]), pre[n][x1 - 1][y1 - 1]);
    };

    for (int i = 0; i <= n; i++) 
        for (int j = 0; j <= n; j++) 
            for (int h = 0; h <= n; h++) 
                pre[i][j][h] = f[i][j][h] = 0;
    
    f[0][1][1] = 1;

    for (int i = 1; i <= n; i++) {
        for (int k = 0; k <= i + 1; k++) {
            for (int a = 1; a <= i; a++) {
                for (int b = 1; b <= i; b++) {
                    pre[k][a][b] = add(pre[k][a][b - 1], f[k][a][b]);
                }
            }
            for (int b = 1; b <= i; b++) {
                for (int a = 1; a <= i; a++) {
                    pre[k][a][b] = add(pre[k][a][b], pre[k][a - 1][b]);
                }
            }
        }
        for (int k = 0; k <= i + 1; k++) {
            for (int a = 1; a <= i + 1; a++) {
                for (int b = 1; b <= i + 1; b++) {
                    f[k][a][b] = add(
                                    add(sum(k - 1, 1, 1, a - 1, b - 1), sum(k - 1, a, b, i, i)), 
                                    add(sum(k, 1, b, a - 1, i), sum(k, a, 1, i, b - 1))
                                    );
                }
            }
        }
    }
    std::cout << sum(m, 1, 1, n, n) << "\n";
}

标签:AtCoder,排列,Beginner,Contest,int,sum,个数,leq,107
From: https://www.cnblogs.com/mingzi47/p/17044080.html

相关文章

  • AtCoder Beginner Contest 134
    AtCoderBeginnerContest134https://atcoder.jp/contests/abc134A-Dodecagon#include<bits/stdc++.h>usingnamespacestd;intmain(){inta;cin......
  • AtCoder Beginner Contest 042
    A-IrohaandHaiku(ABCEdition)#include<bits/stdc++.h>usingnamespacestd;int32_tmain(){inta=2,b=1;for(inti=1,x;i<=3;i++......
  • 2022ccpc绵阳站 2022 China Collegiate Programming Contest (CCPC) Mianyang Onsite
    C.​​CatchYouCatchMe​​题目大意:给你n条路径构成一个无向树,结点编号为1~n。在这棵树中,结点1为出口,其他所有结点上都有一只蝴蝶。每一分钟,每只蝴蝶都会沿着一条树的......
  • [Codeforces Round #822 (Div. 2)](https://codeforces.com/contest/1734)
    CodeforcesRound#822(Div.2)ProblemF.ZerosandOnes解法定义:\(f(x)\)为在\(S\)串中位置为\(x\)的值。显然\(f(x)\in0,1\)有一重要性质:若\(f(x)\)为1,那么二进制......
  • AtCoder Beginner Contest 133
    AtCoderBeginnerContest133https://atcoder.jp/contests/abc133A-TorT#include<bits/stdc++.h>usingnamespacestd;intmain(){inta,b,n;ci......
  • AtCoder Beginner Contest 171
    A-αlphabet(abc171a)题目大意给定一个字母,其大写字母则输出A,否则输出a。解题思路isupper函数或者在'A'与Z之间即为大写字母。神奇的代码#include<bits/stdc+......
  • contest739E. Gosha is hunting 题解报告
    题目地址题意:现在一共有\(n\)只神奇宝贝。你有\(a\)个『宝贝球』和\(b\)个『超级球』。『宝贝球』抓到第\(i\)只神奇宝贝的概率是\(p_i\),『超级球』抓到的......
  • AtCoder284 D - Happy New Year 2023
    AtCoder284D-HappyNewYear2023[Editorial](Editorial-AtCoderBeginnerContest284)Youaregivenapositiveinteger\(N\).Itisknownthat\(N\)canbe......
  • AtCoder Beginner Contest 284
    A-SequenceofStrings#include<bits/stdc++.h>usingnamespacestd;int32_tmain(){intn;cin>>n;vector<string>s(n);for(auto&i:s)......
  • Atcoder ABC112D Partition
    链接难度:\(\texttt{1025}\)找到最大的正整数\(x\)使得\(m\modx=0\)且\(\frac{m}{x}\gen\)。难度在于读题,简化后就简单的一批了。暴力都能过。枚举\(m\)的......