山東省第五屆ACM大學生程式設計競賽-Hearthstone II(組合數學-第二類Stirling數)

kewlgrl發表於2016-04-22

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;
}


相關文章