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, where in first 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 first 3positions 1 is in 1st position and 3 in 3rd position. Soexactly 2 of its first 3 are in there initial position.

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

 

Input

The first line ofinput is an integer T(T<=1000) that indicates the number of testcases. 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. Lookat the sample for clarification.

 

SampleInput                             Outputfor Sample Input


1

5 3 2


Case 1: 12

 


Problem Setter : Md. Arifuzzaman Arif

Special Thanks : Abdullah Al Mahmud, Jane Alam Jan

题意:可以把序列1-n任意重排,但重排后的前m个位置中恰好要有k个是不变的,输入整数n,m,k,输出重排数%1000000007.

思路:首先从前m个选出k作为不变的,然后剩下的n-k个再任意重排,也是从中选出i个来作为不变的,剩下的错排。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long ll;
using namespace std;
const int maxn = 1005;
const ll mod = 1000000007;

ll dp[maxn], C[maxn][maxn];
int n, m, k;

void init() {
	memset(C, 0, sizeof(C));
	C[0][0] = 1;
	for (int i = 1; i < maxn; i++) {
		C[i][0] = C[i][i] = 1;
		for (int j = 1; j < i; j++)
			C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
	}

	dp[1] = 0, dp[0] = dp[2] = 1;
	for (int i = 3; i < maxn; i++)
		dp[i] = ((i - 1) * (dp[i-2] + dp[i-1]) % mod) %  mod;
}

ll solve() {
	ll ans = 0;
	int t = n - m;
	for (int i = 0; i <= t; i++)
		ans = (ans + C[t][i] * dp[n-k-i]) % mod;
	return (ans * C[m][k]) % mod;
}

int main() {
	init();
	int cas = 1;
	int t;
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d%d", &n, &m, &k);
		printf("Case %d: %lld\n", cas++, solve());
	}
	return 0;
}
时间: 2024-10-07 16:37:12

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 ?rst N natural numbers. You canearrange this sequence in many ways. There will be N! di?erent arrangements. You have to calculatethe number of arrangement of ?rst 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 10539 - Almost Prime Numbers(数论)

题目链接:uva 10539 - Almost Prime Numbers 题目大意:给出范围low~high,问说在这个范围内有多少个数满足n=pb,(p为素数). 解题思路:首先处理出1e6以内的素数,然后对于每个范围,用solve(high)?solve(low?1),solve(n)用来处理小于n的满足要求的数的个数.枚举素数,判断即可. #include <cstdio> #include <cstring> typedef long long ll; const int

uva 10712 - Count the Numbers(数位dp)

题目链接:uva 10712 - Count the Numbers 题目大意:给出n,a,b:问说在a到b之间有多少个n. 解题思路:数位dp,dp[i][j][x][y]表示第i位为j的时候,x是否前面是相等的,y是否已经出现过n.对于n=0的情况要特殊处理前导0,写的非常乱,搓死. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using na

uva 1530 - Floating Point Numbers(数论)

题目链接:uva 1530 - Floating Point Numbers 题目大意:给出一个16位的二进制数,用来表示一个浮点数,第一位为符号,1~7位表示一个十进制的数s,e=63-s;剩下的8位为小数部分,默认整数部分为1,得到f,然后最后a=f*2^e,要求用科学计数法输出a. 解题思路:模拟就好了,注意0的情况特殊处理,以及科学计数法的整数部分不能为0. #include <cstdio> #include <cstring> #include <cmath>

UVA 11582 Colossal Fibonacci Numbers!(打表+快速幂)

Colossal Fibonacci Numbers! The i'th Fibonacci number f (i) is recursively defined in the following way: f (0) = 0 and f (1) = 1 f (i+2) = f (i+1) + f (i)  for every i ≥ 0 Your task is to compute some values of this sequence. Input begins with an int

UVA 11582 Colossal Fibonacci Numbers! 找循环节

注意n=1的情况 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #inc

UVa 11481 (计数) Arrange the Numbers

居然没有往错排公式那去想,真是太弱了. 先在前m个数中挑出k个位置不变的数,有C(m, k)种方案,然后枚举后面n-m个位置不变的数的个数i,剩下的n-k-i个数就是错排了. 所以这里要递推一个组合数和错排数. 顺便再复习一下错排递推公式,Dn = (n-1)(Dn-1 + Dn-2),D0 = 1,D1 = 0. 这里强调一下D0的值,我之前就是因为直接从D1和D2开始递推的结果WA 1 #include <cstdio> 2 typedef long long LL; 3 4 const