一道比较好的题,虽然不难,不过该考察的细节都考察了,不容易ac
很显然的概率dp dp[i][j] 表示前i个区间,选取了j个区间有首位为1的概率,然后答案就是求和。
坑点1:统计数位的时候,细节很多稍不注意就弄错。
坑点2:统计数位的时候,用Ull才能防止1e18*10爆炸
坑点3:要统计首位为1的区间为0的情况
坑点4:概率是求和,而不是dp[i][j] = max(dp[i-1][j-1] * a[i], dp[i-1][j])
坑点5:如果用ull统计数位的话,最后先转double再相减会失去精度,double会先转化为科学技术法再计算
//
// Created by Running Photon on 2016-03-13
// Copyright (c) 2015 Running Photon. All rights reserved.
//
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <sstream>
#include <set>
#include <vector>
#include <stack>
#define ALL(x) x.begin(), x.end()
#define INS(x) inserter(x, x,begin())
#define ll long long
#define ull unsigned long long
#define CLR(x) memset(x, 0, sizeof x)
using namespace std;
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1e6 + 10;
const int maxv = 1e3 + 10;
const double eps = 1e-10;
ll n;
double a[maxv];
ull get(ull u) {
if(u == 0) return 0;
if(u == 1) return 1;
ull cnt = 1;
ull res = 0;
ull tmp = 1;
while(tmp * 10 <= u) {
res += cnt;
tmp *= 10;
cnt *= 10;
// cout << tmp << endl;
}
if(u / tmp > 1) res += tmp;
else res += u % tmp + 1;
return res;
}
double dp[maxv][maxv];
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
// ios_base::sync_with_stdio(0);
while(scanf("%I64d", &n) != EOF) {
for(int i = 1; i <= n; i++) {
ll l, r;
scanf("%I64d %I64d", &l, &r);
ull R = get(r);
ull L = get(l - 1);
// cout << R << ' ' << L << endl;
a[i] = 1.0 * (R - L) / (r - l + 1.0);
// printf("a[%d] = %f\n", i, a[i]);
}
double k;
scanf("%lf", &k);
CLR(dp);
dp[0][0] = 1;
for(int i = 1; i <= n; i++) {
for(int j = 0; j <= i; j++) {
dp[i][j] = dp[i-1][j] * (1.0 - a[i]);
if(j)
dp[i][j] += dp[i-1][j-1] * a[i];
// printf("dp[%d][%d] = %f\n", i, j, dp[i][j]);
}
}
double ans = 0;
for(ll i = 0; i <= n; i++) {
if((double)100 * i >= k * n - eps) {
// printf("i = %d\n", i);
ans += dp[n][i];
}
}
printf("%.10f\n", ans);
}
// for(int i = 1; i <= 101; i++) {
// printf("i = %d %lld\n", i, get(i));
// }
return 0;
}