HDU 3944 DP? 【组合数取模+阶乘预处理】
2017-01-26 12:37
387 查看
题意:从杨辉三角顶部走到的第n行第m列有很多种走法,求出这些走法中所经过的数之和的最小值。
首先稍加分析得出答案的组合表达式
C(n+1,m+1,p)+m (mod p) 这是在2m>n时的结果(若不是变换一下m=n-m)
然后就是套用模板实现,首先p是每组数据不同,但是p<10^4,素数非常有限,为避免超时可以先打一个素数表(得出这个范围内的素数不超过1300个),然后针对每个素数算出阶乘表与逆元表。
上述办法在空间复杂度上将将好,代码如下:
首先稍加分析得出答案的组合表达式
C(n+1,m+1,p)+m (mod p) 这是在2m>n时的结果(若不是变换一下m=n-m)
然后就是套用模板实现,首先p是每组数据不同,但是p<10^4,素数非常有限,为避免超时可以先打一个素数表(得出这个范围内的素数不超过1300个),然后针对每个素数算出阶乘表与逆元表。
上述办法在空间复杂度上将将好,代码如下:
#include<stdio.h> #include<string.h> typedef long long LL; LL fac[10005][10005]; //阶乘表 LL inve[10005][10005]; //素数表 int p[1300],num=0; int vis[10005]; void cpnl() // cpnl means creat prime number list { memset(vis,0,sizeof(vis)); for(int i=2;i<=10000;i++) if (!vis[i]) { p[num++]=i; for(int j=i;j<=10000;j+=i) vis[j]=1; } } LL qmod(LL a,LL b,LL mod) //快速幂 { LL ans=1; a=a%mod; while(b) { if(b&1==1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } LL inv(LL a,LL p) //求a在模p下的乘法逆元(p是素数) { return qmod(a,p-2,p); } void cal_table() //计算阶乘表 { for(int n=0;n<num;n++) { fac[p ][0]=inve[p ][0]=1; for(int i=1;i<p ;i++) { fac[p ][i]=fac[p ][i-1]*i%p ; inve[p ][i]=inv(fac[p ][i],p ); } } } LL C(LL n,LL m,LL p) //组合数 { if(n<0 || m<0 || m>n) return 0; if(n==m) return 1; return fac[p] *inve[p][m]%p*inve[p][n-m]%p; } LL Lucas(LL n, LL m,LL p) { if(m == 0) return 1; return C(n % p, m % p,p) * Lucas(n / p, m / p,p) % p; } int main() { cpnl(); cal_table(); LL n,m,p; int t=1; while(~scanf("%lld%lld%lld",&n,&m,&p)) { if(n-m>m) m=n-m; printf("Case #%d: %lld\n",t++,(Lucas(n+1,m+1,p)+m)%p); } return 0; }
相关文章推荐
- hdu 3944 DP? (预处理+卢卡斯定理)
- hdu 3944 DP? 组合数学与数论的结合
- HDU 3944 DP? [Lucas定理 诡异的预处理]
- HDU 3944-DP?(Lucas定理+预处理)
- 【HDU】3944 - DP?(Lucas & 逆元 & 大组合数 & 打表)
- [HDU 3944] DP?组合数 Lucas定理
- HDU 3944 DP?------Lucas 大组合数取余
- HDU3944 DP? (LUCAS定理+阶乘预处理)
- HDU 1799 循环多少次?(排列组合,dp)
- HDU-4661 Message Passing 树形DP,排列组合
- hdu1428 记忆化搜索(BFS预处理最短路径和+DP+DFS)
- 排列组合(二) - HDU 1436 dp
- hdu 3811 用状态压缩DP 解决看似组合数学的题目
- HDU 5282 Senior's String (两次dp LCS预处理)
- HDU 4945 2048 DP 组合
- 【DP|数学+预处理】HDU-1227 Fast Food
- hdu 4791 dp预处理+二分
- hdu 湫秋系列故事——安排座位(组合dp)
- hdu 1799 循环多少次(DP,排列组合Cn(m))
- HDU 3681 Prison Break (二分答案+状压DP+bfs预处理)