• light oj 1095


    1095 - Arrange the Numbers

    Consider this sequence {1, 2, 3 ... N}, as an initial sequence of first N natural numbers. You can rearrange this sequence in many ways. There will be a total of N! arrangements. You have to calculate the number of arrangement of first N natural numbers, where in first M positions; exactly K numbers are in their initial position.

    For Example, N = 5, M = 3, K = 2

    You should count this arrangement {1, 4, 3, 2, 5}, here in first 3 positions 1 is in 1st position and 3 in 3rd position. So exactly 2 of its first 3 are in there initial position.

    But you should not count {1, 2, 3, 4, 5}.

    Input

    Input starts with an integer T (≤ 1000), denoting the number of test cases.

    Each case contains three integers N (1 ≤ N ≤ 1000), M (M ≤ N), K (0 < K ≤ M).

    Output

    For each case, print the case number and the total number of possible arrangements modulo 1000000007.

    Sample Input

    Output for Sample Input

    2

    5 3 2

    10 6 3

    Case 1: 12

    Case 2: 64320

    分析:先从m个数中选出k个数待在自己位置上(c(m, k)), 然后在剩下n-k个数中,有n-m个数可以待在自己原来的位置上,故每局n-m个数有多少个数在自己原来的位置上,剩下的 n - k - i 个数 就是一个错排列了。

    (错排列 : D[i] = (i-1) * (D[i-1] + D[i-2] ) ; )

    代码:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<iostream>
    #include<algorithm>

    using namespace std;
    #define N 1100
    #define INF 0x3f3f3f3f
    #define mod 1000000007

    long long c[N][N], d[N];
    void init()///组合数c(n, m)的的值存在c数组中。
    {
    c[0][0] = 1;

    for(int i = 1; i < N; i++)
    {
    c[i][0] = c[i][i] = 1;

    for(int j = 1; j < i; j++)
    {
    c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod;
    }
    }
    d[1] = 0;
    d[2] = d[0] = 1;
    for(int i = 3; i < N; i++)
    d[i] = (i-1) * (d[i-1] + d[i-2]) % mod;///错排列 : D[i] = (i-1) * (D[i-1] + D[i-2] )
    }

    long long solve(int n, int m, int k)
    {
    long long ans = 0;

    for(int i = 0; i <= n - m; i++)///i表示在n-m数中选i个数呆在自己原来的位置。
    ans = (ans + (c[n-m][i] * d[n-k-i]) % mod) % mod;///c[n-m][i] * d[n-k-i]表示在n-m数中选i个数呆在自己原来的位置,剩下n-k-i都不呆在自己位上的数错排列得到的排列数。

    return ans * c[m][k] % mod;
    }
    int main()
    {
    int T, cas;
    int n, m, k;
    scanf("%d", &T);
    cas = 0;
    init();
    while(T--)
    {
    cas++;

    scanf("%d%d%d", &n, &m, &k);

    long long ans = solve(n, m, k);

    printf("Case %d: %lld ", cas, ans);


    }

    return 0;
    }

  • 相关阅读:
    excel导入phpmyadmin
    Python 教程资源
    SAE部署Python-让云端自动运行Python代码
    python socket 超时设置 errno10054
    使用python一步一步搭建微信公众平台(一)
    PHP读取MySQL数据
    php连接mysql并读取数据
    php分页例子实现读取mysql数据分页显示
    51Nod1305 Pairwise Sum and Divide
    SPOJ SUBXOR
  • 原文地址:https://www.cnblogs.com/dll6/p/7183366.html
Copyright © 2020-2023  润新知