C. Two Arrays,组合数学

本文解析了Codeforces Round 80中C题“Two Arrays”的解题思路,通过将两个数组连接并应用组合数学中的隔板法,巧妙地解决了问题。详细介绍了如何使用动态规划和组合数计算满足特定条件的数组对数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Educational Codeforces Round 80 (Rated for Div. 2) C. Two Arrays

https://codeforces.com/contest/1288/problem/C
You are given two integers n and m. Calculate the number of pairs of arrays (a,b) such that:

the length of both arrays is equal to m;
each element of each array is an integer between 1 and n (inclusive);
ai≤bi for any index i from 1 to m;
array a is sorted in non-descending order;
array b is sorted in non-ascending order.
As the result can be very large, you should print it modulo 109+7.

思路:
之前想了个复杂度巨高的dp,有兴趣可以看这里https://blog.youkuaiyun.com/xing_mo/article/details/103982101

可以考虑将a,b数组连起来形成一个b[1],b[2],…,b[m],a[m],a[m-1],…,a[1]的数组,长度为2m且非严格递减,取值都在[1,n]之间(与原问题等价),就相当于有n个盒子排成一排,由他们的顺序决定所取的数字(即n个不同的盒子),然后将2m个相同的小球放进去,允许空盒子存在(将这些小球放的盒子标号从大到小连起来就组成了一个满足条件的数组),由隔板法得方案数为 C 2 m + n − 1 n − 1 C_{2m+n-1}^{n-1} C2m+n1n1

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MOD = 1e9+7;
ll fac[1025],inv[1025];
inline int qpow(int a,int b)
{
	int ans = 1;
	while(b)
	{
		if(b&1) ans = 1ll * ans * a%MOD;
		a = 1ll * a * a % MOD;
		b >>= 1;
	}
	return ans;
}
inline void getInv(int k)
{
	fac[0] = 1;
	for(int i = 1;i <= k;++i)
		fac[i] = fac[i-1] * i % MOD; 
	inv[k] = qpow(fac[k],MOD-2);
	for(int i = k-1;i >= 0;--i)
		inv[i] = inv[i+1] * (i+1) % MOD;
}
int n,m;
int main()
{
	getInv(1020);
	while(~scanf("%d%d",&n,&m))
		printf("%lld\n",fac[2*m+n-1]*inv[2*m]%MOD*inv[n-1]%MOD);
	return 0;
}
if (thisMonthEffectValue.compareTo(lastMonthEffectValue) == 0) { item.setReason(ReasonDemeritPointsType.ONE.getReason()); } else if (thisMonthEffectValue.compareTo(lastMonthEffectValue) > 0 && effectDifferenceValue.compareTo(BigDecimal.ZERO) < 0) { //本月功效对比上月上升,且大于浮动值 item.setReason(ReasonDemeritPointsType.TWO.getReason()); } else if (thisMonthEffectValue.compareTo(lastMonthEffectValue) > 0 && effectDifferenceValue.compareTo(effectFloatValue) > 0) { //本月功效对比上月上升,且大于浮动值 item.setReason(ReasonDemeritPointsType.TWO.getReason()); } else if (thisMonthEffectValue.compareTo(lastMonthEffectValue) > 0 && effectDifferenceValue.compareTo(effectFloatValue) < 0) { item.setReason(ReasonDemeritPointsType.THREE.getReason()); } else if (thisMonthEffectValue.compareTo(lastMonthEffectValue) > 0 && effectDifferenceValue.compareTo(effectFloatValue) == 0) { item.setReason(ReasonDemeritPointsType.FOUR.getReason()); } else if (thisMonthEffectValue.compareTo(lastMonthEffectValue) < 0 && effectDifferenceValue.compareTo(effectFloatValue) > 0) { item.setReason(ReasonDemeritPointsType.FIVE.getReason()); } else if (thisMonthEffectValue.compareTo(lastMonthEffectValue) < 0 && effectDifferenceValue.compareTo(effectFloatValue) < 0) { item.setReason(ReasonDemeritPointsType.SIX.getReason()); } else if (thisMonthEffectValue.compareTo(lastMonthEffectValue) < 0 && effectDifferenceValue.compareTo(effectFloatValue) == 0) { item.setReason(ReasonDemeritPointsType.SEVEN.getReason()); }优化
最新发布
04-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值