山东省第五届ACM大学生程序设计竞赛-Hearthstone II(组合数学-第二类Stirling数)

Hearthstone II

Time Limit: 2000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

The new season has begun, you have n competitions and m well prepared decks during the new season. Each competition you could use any deck you want, but each of the decks must be used at least once. Now you wonder how many ways are there to plan the season — to decide for each competition which deck you are going to used. The number can be very huge, mod it with 10^9 + 7.
 

输入

The input file contains several test cases, one line for each case contains two integer numbers n and m (1 ≤ m ≤ n ≤ 100).
 

输出

One line for each case, output one number — the number of ways.

示例输入

3 2
100 25

示例输出

6
354076161

提示

 

来源

2014年山东省第五届ACM大学生程序设计竞赛

题目意思:

输入两个数n,m,n是总数,n个中有m个是备选的。
要在m中至少选一个,求总数n中共有多少种组合的情况。

例如题目中的3 2:
即n=3,有A B C三个数;m=2,A B备选但必须至少选一个;
所有所有可能的选法是:
A
B
A B
A C
B C
A B C
就是说选法中必须要有 A B 中的至少一个。

解题思路:

(传送门→)组合数学-第二类Stirling数
但是本题中m可区分,对于第二类Stirling数中求得的是m不可区分的情况下所有的组合总数。
所以需要用for循环遍历,把1~m这m种情况下的S全部相加起来才是本题的结果。



/*
* Copyright (c) 2016, 烟台大学计算机与控制工程学院
* All rights reserved.
* 文件名称:Stirling.cpp
* 作    者:单昕昕
* 完成日期:2016年4月22日
* 版 本 号:v1.0
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
long long s[101][101];
const long long mod=1000000007;
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {//初始化
        memset(s,0,sizeof(s));
        s[n][1]=1;
        s[n][n]=1;
        s[1][1]=1;
        int i,j;
        for(i=2; i<=100; i++)//先根据数据范围把所有s求出来
            for(j=1; j<=i; j++)
                s[i][j]=(s[i-1][j-1]+j*s[i-1][j])%mod;
        long long ans=s[n][k];
        for(i=2; i<=k; i++)//根据题意,k可区分
        {
            ans*=i;
            if(ans>=mod)
                ans%=mod;
        }
        printf("%lld\n",ans);
        //cout<<ans<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值