• C1. 组队活动 Small(BNUOJ)


    C1. 组队活动 Small

    Time Limit: 1000ms
    Memory Limit: 131072KB
    64-bit integer IO format: %lld      Java class name: Main

    BNU ACM校队一共有n名队员,从1n标号,现在n名队员要组成若干支队伍来相互学习、共同进步,为了保证学习效率,每支队伍至多有m名队员,你需要计算出一共有多少种不同的组队方案。两个组队方案被视为不同的,当且仅当存在至少一名队员在两种方案中有不同的队友。

    Input

    第一行是一个正整数T(T leq 5),表示测试数据的组数,

    对于每组测试数据,

    输入只有一行,包含两个整数n(1 leq n leq 1000)m(1 leq m leq 1000)

    Output

    对于每组测试数据,

    输出一行,包含一个整数,表示不同的组队方案的个数,由于方案数可能很大,请对998244353(7 	imes 17 	imes 2^{23}+1)取模后输出。

    Sample Input

    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 ",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             else
    25 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                 else
    47                 {
    48                     dp[i]=(dp[i]+(C[i-1][j]*dp[i-1-j])%E)%E;
    49                 }
    50             }
    51         }
    52         printf("%lld ",dp[p]);
    53     }
    54     return 0;
    55 }
    油!油!you@
  • 相关阅读:
    1.两数之和
    数据库连接情况查询
    你有哪些一直坚持的好习惯2?
    你有那些一直坚持的好习惯1?
    建立保持时间的理解
    verilog之不常用语句
    用于vivado的TCL脚本创建工程
    VIVADO原理图中的概念
    vscode编写的程序中文乱码怎么办?
    c# SendInput模拟输入字符和按键
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5181122.html
Copyright © 2020-2023  润新知