标签:
题意:给定一个数 n ,表示一共有 n 步,然后你可以迈一步也可以迈两步,但是左腿和右腿的一步和两步数要一样,并且两步数不小于一步数,问你有多少种方式。
析:虽然是排列组合,但还是不会做。。。。。水啊。
思路是先分开算,先算左腿的,再算右腿的,对左腿先枚举2步的,然后再算一步的,主要是这个怎么算,我就迷茫了,。。。。
其实并不难,我们先假设左腿有 i 个1步的和 j 个两步的,那么组合数有多少呢?很明显么,就是C(i+j, i)么,就是找 i 位置给 i。
那么剩下的就简单了。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include <set> #include <queue> #include <algorithm> #include <vector> #include <map> #include <cctype> #include <stack> using namespace std; typedef long long LL; typedef pair<int, int> P; const int INF = 0x3f3f3f3f; const double inf = 0x3f3f3f3f3f3f; const double PI = acos(-1.0); const double eps = 1e-8; const int maxn = 50 + 5; const int mod = 1e9 + 7; const char *mark = "+-*"; const int dr[] = {-1, 0, 1, 0}; const int dc[] = {0, 1, 0, -1}; int n, m; inline bool is_in(int r, int c){ return r >= 0 && r < n && c >= 0 && c < m; } inline int Min(int a, int b){ return a < b ? a : b; } inline int Max(int a, int b){ return a > b ? a : b; } LL c[maxn][maxn]; void init(){ for(int i = 0; i < 52; ++i) c[i][0] = 1; for(int i = 0; i < 52; ++i) for(int j = 1; j <= i; ++j) c[i][j] = c[i-1][j] + c[i-1][j-1]; } LL solve(){ int t = n/2; int i = t/2; LL ans = 0; while(i >= t - 2*i){ int j = t - 2 * i; ans += c[i+j][i] * c[i+j][j]; --i; } return ans; } int main(){ init(); int T; cin >> T; while(T--){ scanf("%d %d", &m, &n); printf("%d ", m); printf("%lld\n", solve()); } return 0; }
标签:
原文地址:http://www.cnblogs.com/dwtfukgv/p/5777909.html