[ABC405E] Fruit Lineup 题解

[ABC405E] Fruit Lineup 题解

思路

可以发现苹果一定在香蕉的前面,所以我们可以将橘子和葡萄插入苹果和香蕉中。

dpidp_idpi 表示将橘子只放在前 iii 个空(共有 a+c+1a+c+1a+c+1 个空)时的方案数。

此时橘子的方案数为将 b−1b-1b1 个橘子放到 iii 个空的方案数(有一个橘子强制放在最后一个,iii 从 0 开始),即为 (b+i−1b−1)\binom{b+i-1}{b-1}(b1b+i1)

葡萄方案数为将 ddd 个葡萄插到 min⁡(c,a+c−i)\min(c,a+c-i)min(c,a+ci) 个空里的方案数(ccc 是为了方止葡萄插到苹果的前面,a+c−ia+c-ia+ci 是为了防止葡萄插到橙子前面),即为 (min⁡(c,a+c−i)+dd)\binom{\min(c,a+c-i)+d}{d}(dmin(c,a+ci)+d)

所以 dpidp_idpi 的状态转移方程为:

dpi=(b+i−1b−1)(min⁡(c,a+c−i)+dd)dp_i=\binom{b+i-1}{b-1}\binom{\min(c,a+c-i)+d}{d}dpi=(b1b+i1)(dmin(c,a+ci)+d)

最终答案为:

∑i=1n(b+i−1b−1)(min⁡(c,a+c−i)+dd)\sum_{i = 1}^{n}\binom{b+i-1}{b-1}\binom{\min(c,a+c-i)+d}{d}i=1n(b1b+i1)(dmin(c,a+ci)+d)

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
ll a,b,c,d,dp[4000010],f[4000010];
ll qpow(ll a,ll b){//快速幂 
	ll ans=1%mod;
	for(;b;b>>=1,a=(a*a)%mod)if(b&1)ans=(ans*a)%mod;
	return ans;
}
ll calc(ll a,ll b){//将a个数插到b个水果周围的空(即为b-1个空)的方案数 
	return f[a+b]*qpow(f[a],mod-2)%mod*qpow(f[b],mod-2)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>a>>b>>c>>d;
	f[0]=1;
	f[1]=1;
	for(int i=2;i<=4e6;i++){//阶乘 
		f[i]=f[i-1]*i%mod;
	}
	ll ans=0;
	for(int i=0;i<=a+c;i++){//dp
		dp[i]=max(calc(b-1,i),1ll)*max(calc(d,min(c,a+c-i)),1ll)%mod;
		ans=(ans+dp[i])%mod;
	}
	cout<<ans;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值