[CF1288C] Two Arrays

给定一个数 (n) 和一个数 (m),让构建两个数组 (a)(b) 满足条件

  • 数组中所有元素的取值在 ([1, n]) 之间
  • (a)(b) 数组长度是 (m)
  • (a) 数组是单调不降的,(b) 数组是单调不增
  • 任意的位置 (i),有 (a_i leq b_i)

Solution

首先很容易想到将 (b) 翻转后接在 (a) 的后面,那么问题就转化为用 ([1,n]) 填一个长度为 (2m) 的序列,使其单调不降的方案数

DP 解法

(f[i][j]) 表示填一个 (i) 长度的序列,最后一位为 (j) 的方案数,于是

[f[i][j]=f[i-1][j]+f[i-1][j-1] ]

暴力转移即可,时间复杂度 (O(nm))

组合

等价于求 (x_1+x_2+...+x_n=2m) 的解的方案数,于是考虑隔板法,答案为 (C_{2m+n-1}^{n-1})

时间复杂度 (O(n))

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

#define int long long
const int mod = 1e9+7;

int qpow(int p,int q) {
    return (q&1 ? p : 1) * (q?qpow(p*p%mod,q/2):1) % mod;
}

int inv(int p) {
    return qpow(p,mod-2);
}

int frac(int p) {
    int res = 1;
    for(int i=2;i<=p;i++) res=res*i%mod;
    return res;
}

int n,m;

signed main() {
    cin>>n>>m;
    cout<<frac(2*m+n-1)*inv(frac(n-1))%mod*inv(frac(2*m))%mod;
}
原文地址:https://www.cnblogs.com/mollnn/p/12536823.html