前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PapaMelon #11计算排列的编号 [组合数学]

PapaMelon #11计算排列的编号 [组合数学]

原创
作者头像
零耗
发布2021-07-16 22:47:04
5770
发布2021-07-16 22:47:04
举报

题目链接

计算排列的编号

题解

  • 本题和 #10 计算第 K 个排列 本质上是一个问题,算是一个逆运用吧
  • 我们按字典序(从小到大)考虑 $n$ 个不同元素的全排列。第一位可能是 $1,2,3 ... n$。
  • 假设第一位是 $2$,说明跳过了所有以 $1$ 开头的排列,它们的数量是 $(n-1)!$,因此我们知道以 $2$ 开头的排列的编号,应该从 $(n-1)!$ 开始计数。
  • 确定了第一位就再确定第二位,以此类推下去
代码语言:txt
复制
#include <iostream>
#include <vector>

using namespace std;

using ll = long long;

vector<ll> f(21);
void init() {
  f[0] = 1;
  for (int i = 1; i <= 20; i++) f[i] = f[i - 1] * i;
}

int main(int argc, char const* argv[]) {
  init();

  int T;
  cin >> T;
  while (T--) {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    vector<int> vis(n + 1, false);

    ll skip = 0;
    for (int i = 0; i < n; i++) {
      int count = 0;
      for (int k = 1; k < a[i]; k++)
        if (!vis[k]) count++;
      skip += count * f[n - i - 1];
      vis[a[i]] = true;
    }
    cout << skip + 1 << endl;
  }

  return 0;
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目链接
  • 题解
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com