地址:http://acm.scs.bupt.cn/onlinejudge/showproblem.php?problem_id=1336
Adventure Submit: 72 Accepted:44 Time Limit: 1000MS Memory Limit: 16384K
Description
Considering that our excellent ACM guys have devoted themselves so much so that they have little time for their “own affairs”. To make a change, they come up with an adventurous idea. They intended to write down their personal contact method on the back of their campus card and “lose” it somewhere, hoping for some kind-hearted girl getting in touch with them, which may be a wonderful reason to treat her a meal and begin a further contact. They decided to put the cards into some books and lose them somewhere. However, a problem rose. Each guy has only one campus card, that is, he has only one method to distribute the card -- just put it into one book. If they have two cards, there are two ways – two cards in one book, or in two different books. If they have three cards, there are five choices – {A, B, C}, {AB, C}, {BC, A}, {AC, B}, {ABC}.
Assuming there are N guys, that is to say, there are N campus cards, your task is to calculate the number of different ways to distribute the them into book(s).
Input
The first line is a positive integer T (1<=T<=20), representing the number of cases. The following T lines, each contains a single integer N (1<=N<=2000), which is the number of campus cards.
Output
For each case, you just have to output the total methods mod 10000 for the N-cards distribution, each per line.
Sample Input
4
1
2
3
100
Sample Output
1
2
5
751
Source
Chiara
代码:
思路:二维数组a[i][j]代表i张卡片放在j本书里的方法数.i张卡片所有分配之和就是a[i][1]+a[i][2]。。。。+a[i][j].
当第i张卡片放到j本书的时候,a[i][j],有两种方法,一种是将第i张卡片与至少其他一张卡片在一起,将第1到i-1张卡片放在j本书里(f[i-1][j]),,再第i张卡片随便放在这几本书里的一本里面(这里有j种情况),即f[i-1][j]*j(2)第i张卡片单独在一本书里,将第1到i-1张卡片放在j-1本书里(f[i-1][j-1]),这里注意的是,题目里没有考虑书的不同,即第i张卡片任意放哪个空书里视为1种情形。如:{AB, C}表示C卡片单独一本书,而不确指哪本书,所以这里应该是f[i-1][j-1]*1
综上所述 就是f[i][j]=(f[i-1][j]*j+f[i-1][j-1]
至于%10000 因为题目output the total methods mod 10000,求模10000的余数
而根据余数定理 A(A=A1+A2+A3...)MOD B=((A1 MOD B)+(A2 MOD B)+(A3 MOD B)+....)MOD B
所以f[i][j]=(f[i-1][j]*j+f[i-1][j-1])%10000 到最后再求个余数Sum=(Sum+f[N][i])%10000;
如果计算f[i][j]不求余,则很快就会溢出,造成错误
#include<iostream>
using namespace std;
int a[2010][2010];
int b[2000];
int main()
{
int i,j,k,n,m;
a[1][1]=1;
for(i=2;i<=2000;i++)
for(j=1;j<=i;j++)
a[i][j]=(a[i-1][j-1]+a[i-1][j]*j)%10000;
for(i=0;i<2000;i++)
b[i]=0;
while(cin>>n)
{
for(i=0;i<n;i++)
{
int sum=0;
cin>>m;
for(j=1;j<=m;j++)
b[i]=(b[i]+a[m][j])%10000;
}
for(i=0;i<n;i++)
cout<<b[i]<<endl;
}
system("pause");
return 0;
}