GYM 101147 G.The Galactic Olympics(dp)

Description
n场不同的比赛,派k个人去,一个人可以参加多场比赛且至少参加一场,每场比赛只能且必须要有一个人参加,问方案数
Input
第一行一整数T表示用例组数,每组用例输入两个整数n和k分别表示比赛数和人数(1<=k<=1e6,1<=n<=1e3)
Output
输出方案数
Sample Input
1
3 2
Sample Output
6
Solution
k>n时显然无解,k<=n时吗,设dp[i][j]表示i场比赛分配给j个人的方案数
j=1时,dp[i][1]=1
j=i时,dp[i][i]=i!
1 < j < i时,dp[i][j]=j*dp[i-1][j-1]+j*dp[i-1][j],第一部分表示如果前i-1场比赛已经分配给了j-1个人,那么第i场比赛必须分配给第j个人,第j个人有j种情况,所以该部分对dp[i][j]的贡献就是j*dp[i-1][j-1];第二部分表示如果前i-1场比赛已经分配给了j个人,那么第i场比赛随便让这j个人中的一个人参加即可,所以这部分对答案的贡献就是j*dp[i-1][j]
Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 1111
const ll mod=1000000007ll;
ll dp[maxn][maxn];
void init()
{
    dp[0][0]=1;
    for(int i=1;i<=1000;i++)
    {
        dp[i][1]=1,dp[i][i]=1ll*i*dp[i-1][i-1]%mod;
        for(int j=2;j<i;j++)dp[i][j]=1ll*j*(dp[i-1][j-1]+dp[i-1][j])%mod;
    }
}
int main()
{
    freopen("galactic.in","r",stdin);
    init();
    int T,n,k;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        if(k>n)printf("0\n");
        else printf("%I64d\n",dp[n][k]);
    }
    return 0;
}

   
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

Description
n场不同的比赛,派k个人去,一个人可以参加多场比赛且至少参加一场,每场比赛只能且必须要有一个人参加,问方案数
Input
第一行一整数T表示用例组数,每组用例输入两个整数n和k分别表示比赛数和人数(1<=k<=1e6,1<=n<=1e3)
Output
输出方案数
Sample Input
1
3 2
Sample Output
6
Solution
k>n时显然无解,k<=n时吗,设dp[i][j]表示i场比赛分配给j个人的方案数
j=1时,dp[i][1]=1
j=i时,dp[i][i]=i!
1 < j < i时,dp[i][j]=j*dp[i-1][j-1]+j*dp[i-1][j],第一部分表示如果前i-1场比赛已经分配给了j-1个人,那么第i场比赛必须分配给第j个人,第j个人有j种情况,所以该部分对dp[i][j]的贡献就是j*dp[i-1][j-1];第二部分表示如果前i-1场比赛已经分配给了j个人,那么第i场比赛随便让这j个人中的一个人参加即可,所以这部分对答案的贡献就是j*dp[i-1][j]
Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 1111
const ll mod=1000000007ll;
ll dp[maxn][maxn];
void init()
{
    dp[0][0]=1;
    for(int i=1;i<=1000;i++)
    {
        dp[i][1]=1,dp[i][i]=1ll*i*dp[i-1][i-1]%mod;
        for(int j=2;j<i;j++)dp[i][j]=1ll*j*(dp[i-1][j-1]+dp[i-1][j])%mod;
    }
}
int main()
{
    freopen("galactic.in","r",stdin);
    init();
    int T,n,k;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        if(k>n)printf("0\n");
        else printf("%I64d\n",dp[n][k]);
    }
    return 0;
}

   
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

猜你喜欢

转载自blog.csdn.net/YingShen_xyz/article/details/116765191