Cyclic Permutations(思维)

题目链接: Cyclic Permutations

大致题意:

给定一个n, 你可以任意排列1-n这n个数字, 并按照下述规则以这n个数字建立一张图:

对于每一个下标i, 分别在它的左右找到离他最近的j1和j2, 且要满足a[i] < a[j], 如果能找到则添加i与j之间的无向边, 否则什么也不做.

询问: 有多少种排列能使得图中出现环.

解题思路:

我们可以模拟最简单的情况(n=3), 我们发现只有213和312两种情况.

我们发现如果要成环. 应该至少存在一个三元组a, b, c. 满足a>b && c>b. (对于多元组, 也一定会包含三元组, 所以考虑三元组的情况即可.) 如果我们正向去想, 会发现情况很复杂, 甚至还需要考虑去重. 但是如果我们反向去想, 对于n个数字, 全排列的种类有n!种, 而对于不符合的情况, 我们用n!减去即可得到答案. 而不符合的情况, 则是对于任意一个三元组a, b, c, 都有a<b || c<b. 我们不妨从大到小放置这n个数, 组成不能成环的情况. 假设n已经被放置在某个位置, 则n-1位于其左侧或者右侧均可以, n-2也是位于左右放置都可以, 我们只要保证放置的顺序不改变(大到小), 且每次放置的位置都挨着之前放置的数字, 这样每当我们放置一个数字x, 与他相邻的(比他先放置的)那个数字一定会大于它. 现在我们就得到了不符合条件的数量是2n-1. 因此得到答案: n! - 2n-1.

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int mod = 1E9 + 7;
int main(void)
{
    int n; cin >> n;
    ll a = 1, b = 1;
    for (int i = 1; i < n; ++i) {
        a = (a * i) % mod; b = (b * 2) % mod;
    }
    a = (a * n) % mod;
    cout << (a - b + mod) % mod << endl;
    return 0;
}

队友强, 夸夸他.

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逍遥Fau

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值