标签:
http://acm.nyist.net/JudgeOnline/problem.php?pid=1076
给出一个N*M的棋盘,左下角坐标是(0,0),右上角坐标是(N,M),规定每次只能向上或者向右走,问从左下角走到右上角,一共有多少种方案。上图是一个4*3的棋盘。
4 3 2 2 0 0
35 6
1 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 7 using namespace std; 8 9 #define ll long long 10 11 ll Permutation(ll a,ll x); 12 13 int main(){ 14 ll m,n; 15 while(scanf("%lld %lld",&m,&n),m||n){ 16 printf("%lld\n",Permutation(m+n,n)); 17 } 18 return 0; 19 } 20 ll Permutation(ll a,ll x){ 21 ll ans=1; 22 for(ll i=1;i<=x;i++) ans=ans*(a-i+1)/i; 23 return ans; 24 } 25
这里想提一点就是,虽然只有部分地方必须longlong,但是类型转换要耗不少时间,故而采取所有地方都使用longlong。
解题思路B:因为如果要到(n, m)点,要么从(n-1, m)点过来,要么从(n, m-1)点过来,设dp[i][j]表示从(0, 0)到(i, j)有多少种方案,
则dp[i][j] = dp[i-1][j] + dp[i][j-1],最后输出dp[n][m]就是答案。
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 #define ll long long 9 #define N 35 10 11 ll dp[N][N]; 12 13 void GetAns(); 14 15 int main(){ 16 GetAns(); 17 int m,n; 18 while(scanf("%d %d",&m,&n),m||n){ 19 printf("%lld\n",dp[m][n]); 20 } 21 return 0; 22 } 23 void GetAns(){ 24 int m=30,n=30; 25 dp[0][0]=1; 26 for(int z=1;z<=60;z++){ 27 for(int i=0;i<=n;i++){ 28 int j=z-i; 29 if(j>m) continue; 30 dp[i][j]=0; 31 if(i) dp[i][j]+=dp[i-1][j]; 32 if(j) dp[i][j]+=dp[i][j-1]; 33 } 34 } 35 }
标签:
原文地址:http://www.cnblogs.com/jiu0821/p/4305703.html