错排:考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排
错排公式:D(n)=(n-1)*(D(n-1)+D(n-2));
公式原理: 第n个元素的位置选为k(0<k<n,k有n-1种选法,k的不同会影响Dn的值)
而第k个元素的位置安排可分为两种情况:
1.安排在第n个位置,等价于k,n交换位置,就是去除k,n,求剩下n-2个元素的错排总数Dn-2;
2.不安排在第n个位置,即等价于k,n交换位置,但第n个元素(原第k个元素)是必须安排在别的位置的,相当于求n-1个元素的错排总数Dn-1;
题目:
作为湖南省著名高校,我校的ACM运动一向开展的非常热烈,各级领导也大力支持(这句话很眼熟)。由于组队的策略太复杂,集训队决定采用一种简单粗暴的组队方法。 (1)有一张排名表,排在第1/4/7/10……名次的队员称为A类队员,排在第2/5/8……名次的队员称为B类队员,排在第3/6/9……名次的队员称为C类队员。排名表中,没有并列排名,即每个队员的排名都是唯一的。
(2)每支队伍必须由A/B/C类队员各1名组成,其中A类队员为队长。上面这两段也很眼熟。
(3)第1/2/3名组成HUNNU1队,第4/5/6名组成HUNNU2队,第7/8/9名组成HUNNU3队,……。 但是这样一来,参赛的各兄弟院校就非常清楚我校的虚实。俗话说,知己知彼,百战不殆。现在被知己知彼了,是极不好的。我们决定将上面的第3条规则修改一下:所有的队伍,都不应包含按原规则应该包含的队员。即,HUNNU1队不应包含第1/2/3名中的任何一个队员,HUNNU2队不应包含第4/5/6名中的任何一个队员,…… 。 当然,头两条规则还是要遵守的。问,在新规则下,我校一共有多少种不同的组队方法。由于这个数量可能非常巨大,我们只需其对2017取模的结果。 对我校而言,两个组队方法是不同的:只需存在某个HUNNUn队,在两个组队方法下所包含的队员不完全相同。注意:我们不考虑队员出现的顺序。即由1/5/9组成的队伍与由9/5/1组成的队伍是相同的。
Input输入有多个案例(不超过10000个),每个案例只有一行,为一个正整数n,表示我校集训队队员总数。保证n是3的倍数且n不大于30000。
Output
每个案例输出一行,为答案。
Sample Input
3
6
Sample Output
0
1
Judge Tips 提示:在第一个案例中,只有1/2/3三名队员,也只有HUNNU1队。因此不可能按照新规则组队。在第二个案例中,可以把1/2/3组成HUNNU2队,把4/5/6组成HUNNU1队(除此之外的任何组队方法都会导致1队包含1/2/3中至少1人而不符合新规则),只有这1种方法。
题目链接: http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11687&courseid=155
按照题意:只需将A、B、C组分别错排,排法互不干扰,即符合乘法原理(错排形成的3*n的表格)组队方法总数为:(An)^3;
#include <iostream>
#include <string.h>
using namespace std;
int a[10001];
//DP的实现:An=(n-1)*(An-1+An-2);
int A(int n)
{
if(a[n]!=-1)return a[n];
return a[n]=( ( A(n-1)+A(n-2) )%2017 )*( (n-1)%2017 ) %2017;
}
int main()
{
int n;
memset(a,-1,sizeof(a));
a[1]=0;
a[2]=1;
while (cin>>n)
{
n/=3;
cout<< ( ( (A(n)*A(n))%2017 )*A(n) )%2017 <<endl;//
}
return 0;
}