蓝桥杯2019第十届国赛_排列数

蓝桥杯2019第十届国赛_排列数

描述
在一个排列中,一个折点是指排列中的一个元素,它同时小于两边的元素,或者同时大于两边的元素。
对于一个 1 ∼ n 的排列,如果可以将这个排列中包含 t 个折点,则它称为一个 t+1 单调序列。
例如,排列 (1,4,2,3) 是一个 3 单调序列,其中 4 和 2 都是折点。
给定 n 和 k,请问 1 ∼ n 的所有排列中有多少个kk 单调队列?
输入描述
输入一行包含两个整数 n, k   ( 1 ≤ k ≤ n ≤ 500 ) n , k ( 1 ≤ k ≤ n ≤ 500 ) k\ (1 \leq k \leq n \leq 500)n,k (1≤k≤n≤500) k (1kn500)n,k(1kn500)
输出描述
输出一个整数,表示答案。答案可能很大,你可需要输出满足条件的排列数量除以 123456 的余数即可。
输入输出样例
示例
输入
4 2
输出
12

代码实现:

#include <bits/stdc++.h>
using namespace std;

int main(void) {
    int n, k;
    cin >> n >> k;
    vector<int> seq(n);
    long long res = 0;
    for (int i = 1; i <= n; ++i) seq[i] = i;
    do {
        int cnt = 1;
        for (int i = 1; i <= seq.size() - 2; ++i) {
            if ((seq[i] > seq[i - 1] && seq[i] > seq[i + 1]) || (seq[i] < seq[i - 1] && seq[i] < seq[i + 1])) {
                cnt++;
            }
        }
        if (cnt == k) res = (res + 1) % 123456;
    } while (next_permutation(seq.begin(), seq.end()));
    cout << res;
    // system("pause");
    return 0;
}

不幸的是,这种方法超时了,另一种方法是动态规划:AcWing 2554. 排列数 O(nk)O(nk) DP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值