题目链接:点击打开链接
题意:
给定n个区间
下面n个区间
从每个区间中任选一个数。则一共选出了n个数
给出K(<=100)
问选出的n个数中 最高位是1的个数 占n个数的百分之K以上的概率是多少。
先求出对于第i个区间 ,选出的数最高位是1的概率P[i]
dp[i][j] 表示前i个数选了j个最高位是1的概率.
////////////////////////////////////// //**********************************// //* ======= lalalalalala ========= *// //* ------------------------------ *// //**********************************// ////////////////////////////////////// /// #include <map> /// #include <set> /// #include <list> /// #include <cmath> /// #include <queue> /// #include <deque> /// #include <vector> /// #include <string> /// #include <cstdio> /// #include <cstdlib> /// #include <cstdarg> /// #include <string.h> /// #include <iostream> /// #include <algorithm> /// ////////////////////////////////////// typedef long long ll; template <class T> inline bool rd(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x = -x; } if (x>9) pt(x / 10); putchar(x % 10 + '0'); } using namespace std; ll solve(ll x){ ll ans = 0, len = 0, high = 0, tmp = x, ten = 1; while (tmp){ len++; high = tmp % 10; tmp /= 10; } for (int i = 1; i < len; i++, ten *= 10) ans += ten; if (high > 1)return ans + ten; else if (high == 1)return ans + x - ten + 1; return ans; } const int N = 1005; int n; double p[N], K; double dp[N][N]; //dp[i][j]表示前i个选了j个1的概率 int main(){ while (cin >> n){ for (int i = 1; i <= n; i++){ ll l, r; rd(l); rd(r); p[i] = (double)(solve(r) - solve(l-1)) / (r - l + 1); } rd(K); memset(dp, 0, sizeof dp); dp[0][0] = 1; for (int i = 0; i < n; i++){ for (int j = 0; j <= i; j++) { dp[i + 1][j] += dp[i][j] * (1 - p[i + 1]); dp[i + 1][j + 1] += dp[i][j] * p[i + 1]; } } double ans = 0; for (int i = 0; i <= n; i++) if (double(i) >= K*n/100.0) ans += dp[n][i]; printf("%.10f\n", ans); } return 0; }
时间: 2024-10-07 18:55:03