[hdu5698]: 瞬间移动(两种方法求组合数)
来源:互联网 发布:推荐淘宝蓝莓苗卖家 编辑:程序博客网 时间:2024/06/08 00:57
瞬间移动
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1178 Accepted Submission(s): 583
Problem Description
有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n 行第m 列的格子有几种方案,答案对1000000007 取模。
Input
多组测试数据。
两个整数n,m(2≤n,m≤100000)
两个整数
Output
一个整数表示答案
Sample Input
4 5
Sample Output
10
Source
2016"百度之星" - 初赛(Astar Round2B)
Recommend
wange2014
题解
自己画出前面几行几列 找个规律出来
类似这个样子
0 0 0 0 0
0 1 1 1 1
0 1 2 3 4
0 1 3 6 10
0 1 4 10 20
此时把这个矩阵斜着看 发现好像杨辉三角的规律
在仔细一想 第n行m列 就等于C(n+m-4,n-2) 或者C(n+m-4,m-2)相等的
于是求出这个组合数就可以了啊
今天学了求这个组合数(乘法逆元)的两种方法:
1.扩展欧几里得求乘法逆元
2.费马小定理+快速幂
代码如下:
1.根据二项式定理直接算C 除的时候不用除直接乘上逆元即可
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#define mod 1000000007#define ll long long using namespace std;int x,y;void exgcd(int a,int b){if(b==0) {x=1;y=0;}else {exgcd(b,a%b);int t=x;x=y;y=t-(a/b)*y;}}//求C(n+m-4,n-2) 二项式定理 int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){ll ans=1;for(int i=1;i<=n+m-4;i++)ans=ans*i%mod;for(int i=1;i<=n-2;i++){exgcd(i,mod);x=(x%mod+mod)%mod;//求逆元 ans=(ans*x)%mod;//乘上逆元 }for(int i=1;i<=m-2;i++){//n+m+4-(n-2)=m-2exgcd(i,mod);x=(x%mod+mod)%mod;ans=(ans*x)%mod;}printf("%lld\n",ans);}return 0;}2.费马小定理+快速幂
用快速幂+费马小定理求组合数
1).扩展欧几里德:b*x+p*y=1 有解,x就是所求
2).费马小定理:b^(p-1)=1(mod p),故 b*b^(p-2)=1(mod p),所以x=b^(p-2)
这样的方法可以算出逆元的另一种求法为:x=b^(p-2)
前提是p是质数 否则费马小定理就不成立
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#define ll long long #define mod 1000000007using namespace std;ll fac[200005];void pre(){//预处理乘方fac[1]=1;for(int i=2;i<=200000;i++)fac[i]=fac[i-1]*i%mod; }ll quick_pow(ll a,ll b){ll ans=1;for(ll i=b;i;i>>=1,a=(a*a)%mod)if(i&1) ans=(ans*a)%mod;return ans;} int main(){pre();int n,m;//for(int i=1;i<=100;i++)//printf("%d ",fac[i]);while(scanf("%d%d",&n,&m)!=EOF){ll ans;ans=fac[n+m-4];//printf("%lld\n",ans);ans=ans*quick_pow(fac[n-2],mod-2)%mod;//printf("%lld\n",quick_pow(fac[n-2],mod-2));ans=ans*quick_pow(fac[m-2],mod-2)%mod;printf("%lld\n",ans);}return 0;}
阅读全文
2 0
- [hdu5698]: 瞬间移动(两种方法求组合数)
- 大组合数取模hdu5698 瞬间移动
- 【组合数学】HDU5698[瞬间移动]题解
- 排列组合 hdu5698 瞬间移动
- hdu5698瞬间移动
- hdu5698 瞬间移动
- 【快速幂+组合数+逆元】HDU5698瞬间移动【2016"百度之星" - 初赛(Astar Round2B)】
- hdu5698 瞬间移动(组合数取摸)(16百度之星round2B)
- hdu5698瞬间移动+杨辉三角+LUCAS
- hdu5698 Lucas 大组合数
- 求组合数(取模)的两种方法
- 【组合数】51Nod 1627 瞬间移动
- 51nod 1627 瞬间移动 组合数
- hdu5698百度之星瞬间移动(数论/卢卡斯定理)
- HDU5698 瞬间移动(费马、逆元)
- HDU 5698 瞬间移动 (组合数 + 阶乘逆元)
- HDU 5698 瞬间移动【组合数+逆元】
- [组合数]求组合数的几种方法总结
- Okhttp拦截器统一异常处理并多次读取response.body().string()
- Javascript 中的神器——Promise
- ArcGIS水文分析实战教程(5)细说流向与流量
- 从零开始搭建一个完善的MVP开发框架(三),对列表型数据请求进行抽象,优化列表型数据的处理
- java多态性
- [hdu5698]: 瞬间移动(两种方法求组合数)
- Python/NodeJS坑记
- 学习互联网架构第十一课(并发类容器之Queue)
- oracle case表达式
- ubuntu系统中安装caffe可视化工具digits
- 【Android】开发干货-技术分享之高仿QQ微信网页加载进度条实现
- 从零开始搭建一个完善的MVP开发框架(四) —对View(Activity,Fragment等)层组件进行封装简化View层的开发
- 学习OpenCV——行人检测&人脸检测(总算运行出来了)
- JSF入门