Paths on a Grid POJ - 1942 排列组合

题意:

从左下角移动到右上角。每次只能向上或者向右移动一格。问移动的轨迹形成的右半边图形有多少种

 

题解:

注意,这个图形就根本不会重复,那就是n*m的图形,向上移动n次,向右移动m次。

 

从左下角移动到右上角的过程就是n个“上”,m个“右”的组合的形式,有多少种移动方式,那就是 C((n+m),n)或者C((n+m),m) C((n+m),n)意思就是从n+m个位置上挑选出来n个位置,这n个位置要向上走,那么剩下m个位置肯定是向右走咯

另外 无符号整型的输入输出用“%u” 无符号长整型的输入输出用“%llu”

 

 本题的N=(n+m),M=min(n,m)

将N,M带入公式,你会发现N!与(N-M)!(N-M是max(n,m))约分后剩下的是N*(N-1)*(N-2)*...(一共m个元素)

 

代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<math.h>
 6 #include<queue>
 7 using namespace std;
 8 typedef unsigned ull;
 9 ull result(ull n,ull m) //求组合C(n,m)(n>m)
10 {
11     ull temp;
12     double ans=1.0;
13     temp=min(n,m);
14     n=n+m;
15     m=temp;
16     while(m>0)
17     {
18         ans=ans*((double)(n--)/(double)(m--));
19     }
20     ans+=0.5;
21     return (ull)ans;
22 }
23 int main()
24 {
25     unsigned m,n;
26     while(true)
27     {
28         scanf("%u%u",&n,&m);
29         if(!m && !n)//承认这题的猥琐吧!竟然有其中一边为0的矩阵,一定要&&,用||会WA
30             break;
31         printf("%u\n",result(n,m));
32         //cout<<<<endl;
33     }
34     return 0;
35 }

 

posted @ 2020-05-13 21:16  kongbursi  阅读(119)  评论(0编辑  收藏  举报