UVA 11481 - Arrange the Numbers 数学

Consider this sequence {1, 2, 3, . . . , N}, as a initial sequence of ?rst N natural numbers. You can
earrange this sequence in many ways. There will be N! di?erent arrangements. You have to calculate
the number of arrangement of ?rst N natural numbers, where in ?rst M (M ≤ N) positions, exactly
K (K ≤ M) numbers are in its initial position.
Example:
For, N = 5, M = 3, K = 2
You should count this arrangement {1, 4, 3, 2, 5}, here in ?rst 3 positions 1 is in 1-st position and
3 in 3-rd position. So exactly 2 of its ?rst 3 are in there initial position.
But you should not count this {1, 2, 3, 4, 5}.
Input
The ?rst line of input is an integer T (T ≤ 1000) that indicates the number of test cases. Next T line
contains 3 integers each, N (1 ≤ N ≤ 1000), M, and K.
Output
For each case, output the case number, followed by the answer modulo 1000000007. Look at the sample
for clari?cation.
Sample Input
1
5 3 2
Sample Output
Case 1: 12

题意:给你 n,m,k,   表示a[i] = 1,2....,n 经过变换后->  前m个数中只有任意 k个数满足 i = a[i]问你方案数

题解:我们  先在前m个数中任意选k个数是满足不变的  即 C(m,k);

   再枚举后n-m个中有多少个数的位置是不变的,C(n−m,x),这样就有n−k−x个数为乱序排列。

   对于y个数乱序排序,我们考虑dp做法,假设已经 求出 y-1,y-2个数的乱序排序数,那么 dp[y] = (y-1)*(dp[y-1]+dp[y-2]);(详见上一题)

//meek///#include<bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<bitset>
#include<vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
using namespace std ;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
#define fi first
#define se second
#define MP make_pair
typedef long long ll;

const int N = 1000+100;
const int M = 1000001;
const int inf = 0x3f3f3f3f;
const ll MOD = 1000000007;

int n, m, k;
ll dp[N], c[N][N];
void init () {
    for (int i = 0; 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;
    }
    dp[0] = 1;
    dp[1] = 0;
    dp[2]  = 1;
    for (ll i = 3; i < N; i++)
        dp[i] = ((dp[i-1] + dp[i-2]) % MOD * (i-1)) % MOD;
}

ll solve () {
    ll ans = 0;
    int t = n - m;
    for(int i = 0;i <= n-m; i++) ans += (c[t][i]*dp[n-k-i]), ans %= MOD;
    return (ans * c[m][k]) % MOD;
}
int main () {
    init();
    int cas = 1 , T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d%d", &n, &m, &k);
        printf("Case %d: %lld\n", cas++, solve());
    }
    return 0;
}

代码

时间: 2024-10-24 04:49:30

UVA 11481 - Arrange the Numbers 数学的相关文章

UVA 11481 - Arrange the Numbers(组合数学)

题目链接:11481 - Arrange the Numbers 题意:序列1-n,进行重排,问最后前m个中有k个仍然位置不变的情况数 思路:之前写过UVA 580, n个数重排,要求每个位置都不同的情况的题目,递推式为dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) 利用这个,这题只要: k个位置C(m, k) * sum(C[n - m][i] (后面n-m个选出i个对应正确匹配) * dp[n - k - i](其余位置全都错排)} 这便是总情况数 代码:

UVA - 11481 Arrange the Numbers

Consider this sequence {1, 2, 3, - , N}, as a initial sequence of firstN natural numbers. You can rearrange this sequence in many ways. Therewill be N! different arrangements. You have to calculate the number ofarrangement of first N natural numbers,

UVA 11481 Arrange the Numbers(组合数学 错位排序)

题意:长度为n的序列,前m位恰好k位正确排序,求方法数 前m位选k个数正确排,为cm[m][k],剩余m - k个空位,要错排,这m - k个数可能是前m个数中剩下的,也可能来自后面的n - m个数 考虑这样一个问题,共n个数,前i位错排的方法数,显然dp[i][0] = i! 递推考虑:处理到第i个数时,等价于前i - 1个数错排的方法数减去在前i - 1个数错排的情况下第i位恰好为i的方法数,后者相当于n - 1个数前i - 1位错排 所以 dp[n][i] = dp[n][i - 1] -

UVA 11582 Colossal Fibonacci Numbers! 数学

n比较小,最多n*n就回出现循环节.... Colossal Fibonacci Numbers! Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Problem F: Colossal Fibonacci Numbers! The i'th Fibonacci number f (i) is recursively defined in the

uva 467 - Synching Signals(暴力+数学)

题目连接:uva 467 - Synching Signals 题目大意:有n个红绿灯,给出红灯的时间t,那么该灯从0时刻开始就以2*t为周期绿黄红三灯交替,时间分别为t-5,5,t.问所这n个等从第一变为有一个灯不为绿灯开始,要多久才能变成所有的灯刚好都为绿灯.时间超过1小时输出unable to synch after one hour. 解题思路:一小时才3600秒,枚举秒数判断即可. #include <cstdio> #include <cstring> #include

uva 618 - Doing Windows(暴力+数学)

题目链接:uva 618 - Doing Windows 题目大意:给出电脑桌面的大小W和H,现在在桌面上有4个窗口,给出窗口的初始大小,问说能不能通过调整各个窗口的大小(长宽比例不能变)使得4个屏幕刚好占满整个屏幕,并且互相不覆盖. 解题思路:其实可以直接暴力出所有情况,不过细节比较多,而且要考虑所有的细节. 我的做法的是先将4个窗口缩小至最小的状态,然后枚举左下角的窗口, 有四种可能 蓝色部分为另外枚举的窗口,3,4种情况要分别保证说长.宽相等,然后S部分就是子问题. 所以用一个二进制数来表

uva live 4123 Glenbow Museum 数学递推

// uva live 4123 Glenbow Museum 数学递推 // // 题目大意: // // 对于一个边平行于坐标轴的多边形,我们可以用一个序列来描述,R和O,R表示 // 该顶点的角度为90度,O表示该定点的角度为270.给定序列的长度.问能由这些RO序 // 列组成的星型多边形(内部存在一个点可以看到所有的节点的多边形)的方法数有多少. // // 解题思路: // // 顶点数一定是序列的长度.n小于4无法组成多边形.n为奇数的时候也不行.设R的个数有 // x个,O的个数

Uva 1069 Always an Integer ( 数学 )

Uva 1069 Always an Integer ( 数学 ) #include <cstdio> #include <cstring> #include <algorithm> #include <cctype> using namespace std; typedef long long LL; #define MAXN 105 #define CLR( a, b ) memset( a, b, sizeof(a) ) LL c[ MAXN ], d

uva 11490 - Just Another Problem(数学)

题目链接:uva 11490 - Just Another Problem 题目大意:有n个士兵,要排列成一个方阵,要求方阵尽量大,于是在方正的中间会空出两个正方形的区域,空出来的局域要求厚度相同,即正方形的四条边向相应方向均再有x行或者列. 解题思路:根据题意可以知道x(6x+7r)=n,x为厚度,r为正方形的边长.接着枚举x,x是n的因子. #include <cstdio> #include <cstring> #include <cmath> typedef l