排列组合简单练习

照相

题目描述

某个班级有N个学生,现在从中选择r个学生出来,从左往右排成一行照相,有多少种不同的排列?答案模10007.

输入格式

一行,N和r。1 <= N<=1000, 1<=r<=N

输出格式

一个整数。

输入样例

1000  2

输出样例

8307

解题思路

本题分两步走:

  1. 选出这r个学生: C N r C{^r_N} CNr
  2. 排列这r个学生: A r r A{^r_r} Arr
    因为是分步执行,所以是乘法原理 C N r × A r r C{^r_N}\times A{^r_r} CNr×Arr

代码

#include
#include

using namespace std;
int N,r;
unsigned long long p=1,ans=1,f[1005][1005];

int main()
{
	freopen("1034.in","r",stdin);
	freopen("1034.out","w",stdout);
	cin>>N>>r;
	for(int i=1;i<=r;i++)
	{
		p*=i;
		p%=10007;
	}
	for(int i=0;i<=N;i++)
	{
		f[i][i]=1;
		f[i][0]=1;
	}
	for(int i=1;i<=N;i++)
		for(int j=1;j<i;j++)
		{
			f[i][j]=f[i-1][j]+f[i-1][j-1];
			f[i][j]%=10007;
		}
	ans=f[N][r]*p%10007;
	cout<<ans;
	return 0;
}


L字符串

题目描述

由小写字母构成的长度是L的字符串,要求相邻的字符不相同,问这样的字符串总共有多少个?答案模10007。

输入格式

一个整数L 。 1 <= L <= 100.

输出格式

一个整数。

输入样例

2

输出样例

650

解题思路

我们单独考虑每一个位置的情况:
第一个位置26个字母可以任意放置,第二个位置不能与第一个位置相同,所以可以放25个字母,第三个位置不能与第二个位置相同,所以可以放25个字母,为什么第三个位置可以放25个字母呢?我们看看以下序列:

位置 1 2 3
放置了的字母 a b ?

前面两个位置是合法的,我们来思考一下第三个位置,因为题目说不与相邻的字母相同,所以第三个位置可填:
a,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
一共25个字母。同理,后面的位置也可填25个字母,由此可以列出以下表格:

位置 1 2 3 ⋯ \cdots L − 1 L-1 L1
可放置的字母方案数 26 25 25 ⋯ \cdots 25

答案就是: 26 × 25 L − 1 26\times 25{^{L-1}} 26×25L1


代码

#include
#include

using namespace std;
int L;
int ans=26;
int main()
{
	freopen("1036.in","r",stdin);
	freopen("1036.out","w",stdout);
	cin>>L;
	/*
	第一个位置可以填26个字母 
	因为题目要求相邻的字符不相同,所以第二个位置可以填25个字母,不能与第一个相同 
	第三个位置也可以填25个字母,不会与第二个位置字母相同
	以此类推: 
				1 	 2 	  3 	...	   L-1 	 L
	answer =	26 * 25 * 25  * ...  * 25  * 25
	*/
	for(int i=1;i<L;i++)
	{
		ans*=25;
		ans%=10007;
	}
	cout<<ans;
	return 0;
}


派水果

题目描述

若一位母亲手里有m个相同的苹果,还有n个相同的梨,在m+n天内分给她的小孩,每天分一个水果,有多少种不同的分派方案?答案模10007。

输入格式

一行,m和n, 1 <= m,n <= 1000。

输出格式

一个整数。

输入样例

2 3

输出样例

10

解题思路

(本题思路作者不是很记得了,所以解释的会略有含糊,还请望各位大佬给出一种十分明确的解释)
从题目可以得知,有 m m m相同的苹果,还有 n n n相同的梨,那么就不属于排列问题了,而是一个组合问题。

在这 m + n m+n m+n天里,怎么组合这 m m m个苹果和 n n n个梨呢?
通过手动模拟样例,我们可以发现,只要求出 m + n m+n m+n m m m n n n中最小的一个数的组合数就可以得到正解了。
因为如果用较大的一个数做计算,会出现一些虽然分配顺序不同,但分配方案相同的情况,不符合题意。
所以本题正解: C m + n m i n ( m , n ) C{_{m+n}^{min(m,n)}} Cm+nmin(m,n)


代码

#include
#include

using namespace std;
int n,m;
int f[3005][3005];

int main()
{
	freopen("1035.in","r",stdin);
	freopen("1035.out","w",stdout);
	cin>>m>>n;
	for(int i=0;i<=m+n;i++)
	{
		f[i][i]=1;
		f[i][0]=1;
	}
	for(int i=1;i<=m+n;i++)
	{
		for(int j=1;j<i;j++)
		{
			f[i][j]=f[i-1][j]+f[i-1][j-1];
			f[i][j]%=10007;
		}
	}
	cout<<f[m+n][min(m,n)]%10007;
	return 0;
}

你可能感兴趣的:(题解)