Atcoder ABC132 D - Blue and Red Balls

D - Blue and Red Balls
Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400 points

Problem Statement
There are K blue balls and N−K red balls. The balls of the same color cannot be distinguished. Snuke and Takahashi are playing with these balls.

First, Snuke will arrange the N balls in a row from left to right.

Then, Takahashi will collect only the K blue balls. In one move, he can collect any number of consecutive blue balls. He will collect all the blue balls in the fewest moves possible.

How many ways are there for Snuke to arrange the N balls in a row so that Takahashi will need exactly i moves to collect all the blue balls? Compute this number modulo 109+7 for each i such that 1≤i≤K.

Constraints
1≤K≤N≤2000
Input
Input is given from Standard Input in the following format:
N K
Output
Print
K lines. The i-th line (1≤i≤K) should contain the number of ways to arrange the N balls so that Takahashi will need exactly i moves to collect all the blue balls, modulo 109+7.

Sample Input 1
Copy
5 3
Sample Output 1
Copy
3
6
1
There are three ways to arrange the balls so that Takahashi will need exactly one move: (B, B, B, R, R), (R, B, B, B, R), and (R, R, B, B, B). (R and B stands for red and blue, respectively).

There are six ways to arrange the balls so that Takahashi will need exactly two moves: (B, B, R, B, R), (B, B, R, R, B), (R, B, B, R, B), (R, B, R, B, B), (B, R, B, B, R), and (B, R, R, B, B).

There is one way to arrange the balls so that Takahashi will need exactly three moves: (B, R, B, R, B).

题意:一共有n个球,其中有k个蓝色的球,n-k个红色的球,现在将k个蓝色的球分成m堆,1≤m≤k
然后和红色的球混合,问你有多少种不同的排列。

思路:很明显这是一个排列组合中的插空法的题目,有n-k个红球,所以有n-k+1个空,在n-k+1个空中插入m堆蓝色的球,很显然不同的排列的个数为C(n-k+1,m);接下来计算将k个球分成m堆的种数,枚举几组可以发现种数为C(k-1,m-1);所以最后的答案就是C(n-k+1,m)*C(k-1,m-1)。

代码:

#include<bits/stdc++.h>
#define LL long long
#define Max 2005
const LL mod=1e9+7;
const LL LL_MAX=9223372036854775807;
using namespace std;
LL C[Max][Max];
void Compare_C(){//打表
    C[0][0]=1;
    for(int i=1;i<Max;i++){
        C[i][0]=C[i][i]=1;
        for(int j=1;j<=i;j++){
            C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
        }
    }
}
int main()
{
    Compare_C();
    int b,r,c;
    scanf("%d%d",&c,&b);
    r=c-b+1;
    for(int i=1;i<=b;i++){
        printf("%lld\n",(C[b-1][i-1]*C[r][i])%mod);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值