HUNNU---第八届校赛<混淆视听>

xiaoxiao2021-02-28  107

做题时,压根没想到是DP题---错排.     错排:考虑一个有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) ) 17 )*( (n-1) 17 ) 17; } 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)) 17 )*A(n) ) 17 <<endl;// } return 0; }

转载请注明原文地址: https://www.6miu.com/read-19407.html

最新回复(0)