C1. 组队活动 Small
Time Limit: 1000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld Java class name: Main
BNU ACM校队一共有名队员,从到标号,现在名队员要组成若干支队伍来相互学习、共同进步,为了保证学习效率,每支队伍至多有名队员,你需要计算出一共有多少种不同的组队方案。两个组队方案被视为不同的,当且仅当存在至少一名队员在两种方案中有不同的队友。
Input
第一行是一个正整数,表示测试数据的组数,
对于每组测试数据,
输入只有一行,包含两个整数、。
Output
对于每组测试数据,
输出一行,包含一个整数,表示不同的组队方案的个数,由于方案数可能很大,请对取模后输出。
Sample Input
2
5 2
20 3
Sample Output
26
721625882
思路:dp。动态转移方程dp[i]=(dp[i]+(C[i-1][j]*dp[i-1-j])%E)%E;其中C为组合数,用杨辉三角法可以求得。考虑当新加入的人,有多少种组队法,也就是和前面的人的组合按照不超过m名队员枚举,所以从前面选出的人就是C[i-1][j],前i-1个人中选j个的选法,然后前i-1剩下的按合理排的方案就为dp[i-1-j].所以两个相乘。
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<string.h> 5 #include<stdlib.h> 6 #include<queue> 7 #include<stack> 8 #include<cstdio> 9 #define sc(x) scanf("%I64d",&x)10 #define pr(x) printf("%I64d",x)11 #define prr(x) printf("%I64d\n",x);12 #define prrr(x) printf("%I64d ",x);13 const long long E=998244353;14 using namespace std;15 long long C[1005][1005];16 long long dp[1005];17 void run()18 {19 int i,j;20 for(i=0; i<=1000; i++)21 for(j=0; j<=i; j++)22 if(j==0||i==j)23 C[i][j]=1;24 else25 C[i][j]=(C[i-1][j-1]+C[i-1][j])%E;26 }//杨晖三角27 int main(void)28 {29 run();30 int i,j,k,p,q;31 scanf("%d",&k);32 while(k--)33 {34 memset(dp,0,sizeof(dp));35 scanf("%d %d",&p,&q);36 dp[0]=1;37 dp[1]=1;38 for(i=2; i<=p; i++)39 {40 for(j=0; j<q; j++)//枚举种类41 {42 if(i-1-j<0)43 {44 break;45 }46 else47 {48 dp[i]=(dp[i]+(C[i-1][j]*dp[i-1-j])%E)%E;49 }50 }51 }52 printf("%lld\n",dp[p]);53 }54 return 0;55 }
时间: 2024-10-13 18:53:08