boj 1336 简单的问题 不过自己没想到 别人解释的~~学习~~

地址: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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值