给你一个数N,代表有N个点,每个点上有一定数量的黄金,你有一个6面的骰子,投到x就走x步,如果超过了N,就再投一次,让你求获得黄金数量的期望值。 题解:
我们可以算出来走每个位置的概率,用这个位置的价值乘以概率,加起来就是期望了。对于一每个点,都可以从在他前面和它的距离<= 6的点转移过来,但是要考虑到,最后面几个点在转移的时候不是乘1/6。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include <iostream> #include <algorithm> #include <string.h> #include <stdio.h> using namespace std; #define ll long long
int main(int argc, char const *argv[]) { int T, n; double p[105]; int a[105];
scanf("%d", &T);
for (int t = 1; t <= T; t++) { scanf("%d", &n); memset(p, 0, sizeof p); p[0] = 1.0; p[n-1] = 1.0;
for (int i = 0; i < n; i++) { scanf("%d", a+i); }
for (int i = 1; i < n-1; i++) { for (int j = i-6 < 0 ? 0 : i-6; j < i; j++) { if (j+6 < n) { p[i] += p[j]/6; } else { p[i] += p[j]/(n-j-1); } } } double ans = a[0]; if (n > 1) ans += a[n-1]; for (int i = 1; i < n-1; i++) ans += p[i]*(double)a[i]; printf("Case %d: %.7lf\n", t, ans); } return 0; }
|
给出一个数字\(D\) 我们可以选择\(1-D\)中可以被\(D\)整除的数字,然后用\(D\)出得到一个新的数字\(D_1\); 然后在找所有\(D_1\)的因子,用\(D_1\)除,直到得到1; 问除的次数的期望值;
题解:
dp转移方程 \[
dp[n] = (\sum_{d|n}{dp[d]}+num)/(num-1), num为n的因子个数,d \ne n
\]
这篇博客有详细推导。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <iostream> #include <cmath> #include <algorithm> #include <string.h> #include <stdio.h> using namespace std; #define ll long long double dp[100005]; int main(int argc, char const *argv[]) { int T, n; dp[1] = 0; for (int i = 2; i <= 100000; i++) { dp[i] = 0; int num = 0; for (int j = 1; j*j <= i; j++) { if (i % j == 0) { dp[i] += dp[j]; num++; if (i/j != j) { num++; dp[i] += dp[i/j]; } } } dp[i] = (dp[i]+num)/(num-1); } scanf("%d", &T);
for (int t = 1; t <= T; t++) { scanf("%d", &n); printf("Case %d: %lf\n", t, dp[n]); } return 0; }
|