欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

P4859-已经没有什么好害怕的了【容斥,dp】

发布时间:2023/12/3 编程问答 53 豆豆
生活随笔 收集整理的这篇文章主要介绍了 P4859-已经没有什么好害怕的了【容斥,dp】 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

正题

题目链接:https://www.luogu.com.cn/problem/P4859


题目大意

两个长度为nnn的序列a,ba,ba,b两两匹配,求ai>bia_i>b_iai>bi的组数比ai<bia_i<b_iai<bi的组数多kkk的方案数。
保证输入数字两两不同


解题思路

其实就是求恰好有n+k2\frac{n+k}{2}2n+kai>bia_i>b_iai>bi的匹配方案。

先设fi,jf_{i,j}fi,j表示到aaa的第iii个,已经选择了jjj组的方案。转移起来比较麻烦,我们不知道bbb中选了哪些。

aaabbb排序后,设lil_ili表示一个最大的数字使得ai>blia_i>b_{l_i}ai>bli,然后就可以dpdpdp
fi,j=fi−1,j+fi−1,j−1×(li−j+1)f_{i,j}=f_{i-1,j}+f_{i-1,j-1}\times(l_i-j+1)fi,j=fi1,j+fi1,j1×(lij+1)

之后发现我们很难固定其他配对的大小,可以考虑容斥,设gig_igi表示至少有iii对满足ai>bia_i>b_iai>bi的方案,那么有gi=fi×(n−i)!g_i=f_i\times (n-i)!gi=fi×(ni)!
然后就可以直接容斥了,因为gig_igi中有(ik)\binom{i}{k}(ki)中方案选出kkk个配对满足,所以容斥系数就是(−1)i−k(ik)(-1)^{i-k}\binom{i}{k}(1)ik(ki)
答案就是
∑i=kn(−1)i−k(ik)gi\sum_{i=k}^n(-1)^{i-k}\binom{i}{k}g_ii=kn(1)ik(ki)gi
时间复杂度O(n2)O(n^2)O(n2)


code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=2100,P=1e9+9; ll n,k,C[N][N],a[N],b[N],f[N][N],g[N],l[N],ans; signed main() {scanf("%lld%lld",&n,&k);if((n+k)&1)return puts("0")&0;k=(n+k)/2;C[0][0]=1;for(ll i=1;i<=n;i++)for(ll j=0;j<=i;j++)C[i][j]=(C[i-1][j]+(j?C[i-1][j-1]:0))%P;for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);for(ll i=1;i<=n;i++)scanf("%lld",&b[i]);sort(a+1,a+1+n);sort(b+1,b+1+n);for(ll i=1;i<=n;i++) for(ll j=1;j<=n;j++)if(b[j]<a[i])l[i]=j;else break;f[0][0]=1;for(ll i=1;i<=n;i++)for(ll j=0;j<=n;j++)f[i][j]=(f[i-1][j]+(j?f[i-1][j-1]*max(l[i]-j+1,0ll)%P:0))%P;for(ll i=n,s=1;i>=0;i--,s=s*(n-i)%P)g[i]=f[n][i]*s%P;for(ll i=k;i<=n;i++){ll tmp=g[i]*C[i][k]%P;(ans+=((i-k)&1)?P-tmp:tmp)%=P;}printf("%lld\n",ans);return 0; } 创作挑战赛新人创作奖励来咯,坚持创作打卡瓜分现金大奖

总结

以上是生活随笔为你收集整理的P4859-已经没有什么好害怕的了【容斥,dp】的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。