atcoder beginner contest 132 Blue and Red Balls(组合数 ,pascal 三角形)

2 篇文章 0 订阅
2 篇文章 0 订阅

题目大意:

有K个蓝球,N-K个红球。这些球排成一行,小明每次收集连续子串的蓝球,现在有K个query,第ith query问的是若小明用i步把蓝球收集完,则这样的球的排列方式有多少种。

题解:

排列组合题目,首先我们假设有X1种排列红球的方法,有X2种排列蓝球的方法。那么本次query有X1 * X2种排列方法。所以问题转化为怎么算X1和X2. 首先看蓝球。蓝球每次query询问相当于分成了i堆,那么每堆分配多少个蓝球对应不同的排列方法。假设把蓝球放成一行,那么其中有K-1个空隙,分成i堆,相当于有i-1个隔板在中间,则隔板的位置总共有多少种放法对应于X2。所以X2=C_{(k-1)}^{(i-1)}。这时候我们看X1的求法,假设我们把红色球放成一行,红球的空隙加上两边总共有N-K+1个,我们定义这个叫红球空档。 这时候X1等于蓝色球的i堆 放在这些空档有几种放法。X1=C_{(N-K+1)}^{(i)},其中的组合数可以用pascal 三角形来算复杂度O(n^2),具体的板子可以看https://www.geeksforgeeks.org/calculate-ncr-using-pascals-triangle/

另外!这里的数字比较大,所以记住组合数计算的时候需要模一下!

AC代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
// Initialize the matrix with 0 
const int MAXN =2e3+10;
const int MAXR =2e3+10+10;
const int MODN=1e9+7;
int l[MAXN][MAXR] = { 0 }; 
  
void initialize() 
{ 
  
    // 0C0 = 1 
    l[0][0] = 1; 
    for (int i = 1; i < MAXN; i++) { 
        // Set every nCr = 1 where r = 0 
        l[i][0] = 1; 
        for (int j = 1; j < i + 1; j++) { 
  
            // Value for the current cell of Pascal's triangle 
            l[i][j] = (l[i - 1][j - 1] + l[i - 1][j])%MODN; 
        } 
    } 
} 
  
// Function to return the value of nCr 
int nCr(int n, int r) 
{ 
    // Return nCr 
    return l[n][r]; 
} 
int32_t main(){
	int n,k;
	initialize();
	cin>>n>>k;
	for(int sta=1;sta<=k;sta++){
		cout<<(nCr(k-1,sta-1)*nCr(n-k+1,sta))%MODN<<endl;
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值