Codeforces 54C First Digit Law 数位dp+概率dp

来源:互联网 发布:兼职淘宝模特南京 编辑:程序博客网 时间:2024/05/16 15:46

题目链接:点击打开链接

题意:

给定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;}


0 0
原创粉丝点击