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](其余位置全都错排)} 这便是总情况数

代码:

#include <stdio.h>
#include <string.h>

const long long MOD = 1000000007;

const int N = 1005;

int t, n, m, k;
long long dp[N], C[N][N];

void init() {
	dp[0] = 1; dp[1] = 0; dp[2] = 1;
	for (int i = 3; i <= 1000; i++)
		dp[i] = (i - 1) * ((dp[i - 2] + dp[i - 1]) % MOD) % MOD;
	for (int i = 0; i <= 1000; 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;
  		}
	}
}

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

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

时间: 2024-08-03 23:52:38

UVA 11481 - Arrange the 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 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

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,

Light oj 1095 - Arrange the Numbers (组合数学+递推)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1095 题意: 给你包含1~n的排列,初始位置1,2,3...,n,问你刚好固定前m个数中的k个数的位置,问你有多少中排列方案.(比如5 3 2有1 4 3 2 5这种方案,1和3固定了) 思路: 前m个取k个就是C(m, k)个方案.然后就是类似错排的思想,设dp[i]为i个数在初始位置各不相同.其中的组合数用逆元算出. ans = dp[m - k] * C(n - m,

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

POJ 1715 Hexadecimal Numbers 组合数学

POJ 1715 Hexadecimal Numbers 组合数学 题目地址 题意: 一个十六进制,最多8位而且每一位都不能重复,求所有符合的数中第n大的数.注意不能有前导0. 分析: 可以发现,第i位的任何一个取值,都有P(unused, i - 1)个数字串,只要从高位向低位,从F到1找过去,看第n个是否在这个区间里面,如果没有的话就把那位置为0,然后找下一位就行了. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: 1715.c

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