dfs + 剪枝, 用最大最小值剪。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int> > using namespace std; const int N = 5e4 + 7; const int M = 10 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-10; int m, n, x, y, ans; double sum[55]; double w; void dfs(int x, int y, double p) { if(p + sum[x + (n - y) - 1] - sum[x - 1] - w < -eps) return; if(p + sum[m] - sum[m - (n - y)] - w > eps) return; if(y == n) { ans++; return; } dfs(x + 1, y, p); dfs(x + 1, y + 1, p + 1.0 / x); } int main() { scanf("%d%d%d%d", &n, &m, &x, &y); w = 1.0 * x / y; for(int i = 1; i <= m; i++) { sum[i] = sum[i - 1] + 1.0 / i; } dfs(1, 0, 0.0); printf("%d\n", ans); return 0; } /* */