首页 > [NOIP模拟测试9]题(Problem) 题解 (组合数全家桶+dp)

[NOIP模拟测试9]题(Problem) 题解 (组合数全家桶+dp)

达哥送分给我我都不要,感觉自己挺牛批。

$type=0:$

跟visit那题类似,枚举横向移动的步数直接推公式:

$ans=sum C_n^i imes C_i^{frac{i}{2}} imes C_{n-i}^{frac{n-i}{2}},i\% 2=0$

$type=1:$

因为不能触碰负半轴,所以可以把右移看成+1,左移看成-1,转化为前缀和大于等于0的问题

于是直接Catalan数就好了。注意是第$frac {n}{2}$项的Catalan。

$Catalan_n=C_{2n}^{n}-C_{2n}^{n-1}$

$type=2:$

观察到数据范围较小,考虑dp。

设$f[i]$为走i步回到原点的方案数,通过枚举第一次回到原点的步数j进行转移。

显然j只能为偶数。

$f[i]=sum f[i-j]*Catalan(frac{j}{2}-1)$

$type=3:$

还是枚举横向走的步数,结合Catalan数求解。

$ans=sum C_n^i*Catalan(frac{i}{2})*Catalan(frac{n-i}{2})$

 

 

#include
#include
#include
using namespace std;
typedef long long ll;
const ll mod=1000000007;
const int N=100005;
int n,op;
ll fac[N<<1],ans,dp[N<<1];
ll qpow(ll a,ll b)
{ll res=1;//a%=mod;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;
}
ll ini()
{fac[0]=1;for(int i=1;i<=(N-5)<<1;i++)fac[i]=1LL*i*fac[i-1]%mod;
}
ll C(ll x,ll y)
{if(y>x)return 0;return fac[x]*qpow(fac[y],mod-2)%mod*qpow(fac[x-y],mod-2)%mod;
}
ll lucas(ll x,ll y)
{if(!y)return 1;return C(x%mod,y%mod)*lucas(x/mod,y/mod)%mod;
}
ll Catalan(ll x)
{return (lucas(x*2,x)-lucas(x*2,x-1)+mod)%mod;
}
void qj1()
{//cout<<2*n<//cout<ans=Catalan(1LL*n/2);cout<endl;
}
void qj0()
{for(int i=0;i<=n;i++){if(i%2)continue;ans+=lucas(1LL*n,1LL*i)%mod*lucas(1LL*i,1LL*i/2)%mod*lucas(1LL*(n-i),1LL*(n-i)/2)%mod,ans%=mod;}cout<endl;
}
void qj3()
{for(int i=0;i<=n;i++){if(i%2)continue;ans+=lucas(1LL*n,1LL*i)*Catalan(1LL*i/2)%mod*Catalan(1LL*(n-i)/2)%mod,ans%=mod;}cout<endl;
}
void qj2()
{dp[0]=1;for(int i=2;i<=n;i+=2)for(int j=2;j<=i;j+=2)dp[i]+=dp[i-j]*4%mod*Catalan(1LL*j/2-1LL)%mod,dp[i]%=mod;cout<endl;
}
int main()
{scanf("%d%d",&n,&op);ini();if(op==1)qj1();else if(op==0)qj0();else if(op==3)qj3();else qj2();return 0;
}

 

转载于:https://www.cnblogs.com/Rorschach-XR/p/11267549.html

更多相关:

  • L1-056 猜数字 (20 分) 一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢。本题就要求你找出其中的赢家。 输入格式: 输入在第一行给出一个正整数N(≤104)。随后 N 行,每行给出一个玩家的名字(由不超过8个英文字母组成的字符串)和其猜的正整数(≤ 100)。 输出格式: 在一行中...

  • 题目链接 题意:给你三个数n,m,k;让你构造出一个nm的矩阵,矩阵元素只有两个值(1,-1),且满足每行每列的乘积为k,问你多少个矩阵。 解法:首先,如果n,m奇偶不同,且k=-1时,必然无解: 设n为奇数,m为偶数,且首先要满足每行乘积为-1,那么每行必然有奇数个-1,那么必然会存在有偶数个-1.。满足每列乘积为-1,那么每列必...

  • Description 有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。 若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci×cj 的价值。 一个数字只能参与一次配对,可以不参与配对。 在获得的价值总和不小于 0 的前提下,求最多进行多少次配对...

  • 快速幂       1 #include 2 #include 3 #include 4 #define LL long long 5 using namespace std; 6 7 LL Pow(LL a, LL b) 8 { 9 LL an...