1. 随机选择一个杯子。
2. 杯子是空的。回合直接结束。
3. 杯子是满的。如果小欧上一回合喝过了水,则回合结束;否则将喝完这杯水,回合结束。
小欧想知道,她喝完所有水的回合数期望是多少?
两个正整数,用空格隔开。
一个浮点数,代表期望的回合数。如果你的答案和正确答案的误差不超过,则认为答案正确。
1 1
1.000000000
只有一杯水,第一回合就可以喝完。
2 1
2.000000000
有50%的概率1回合喝完,有25%的概率需要2回合 ,有12.5%的概率需要3回合……
总期望为0.5*2+0.25*3+0.125*4+……=2
2 2
4.000000000
第一回合有100%的概率喝一杯水。第二回合无论是否选到有水的杯子都不会喝水。0.5*3+0.25*4+0.125*5+...=4
#include <iostream> using namespace std; //大致的运行逻辑 double process(double k,double n,bool dr){ if(k==0){ return 0; } if(dr){ return process(k,n,0)+1; }else { return double(n/k)+process(k-1,n,1); } } //改动态规划 int main() { int n; int k; cin>>n>>k; double dp[k][1]; dp[0][0]=0; dp[0][1]=0; for(int i=1;i<=k;i++){ dp[i][0]= double(n)/i+dp[i-1][1]; dp[i][1]=dp[i][0]+1; } printf("%f",dp[k][0]); } // 64 位输出请用 printf("%lld")
import java.util.Scanner; public class Main { static int nCup; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); nCup = scanner.nextInt(); int kWater = scanner.nextInt(); double expect = (double) nCup / kWater + computeExpectation(kWater - 1, true); System.out.println(expect); scanner.close(); } private static double computeExpectation(int kWater, boolean drunk) { if (kWater == 0) { return 0; } return drunk ? 1 + computeExpectation(kWater, false) : (double) nCup / kWater + computeExpectation(kWater - 1, true); } }
#include <bits/stdc++.h> #include <iostream> using namespace std; double func(int n, int k) { if (k == 1) { double r = 0; int round = n < 100 ? 20 * n : 15 * n; for (int i = round; i >= 1; i--) { r += i * pow(1.0 * (n - 1) / n, i - 1) / n; } return r; } double r = func(n, 1) + k - 1; double tmp = 0; for (int i = 2; i <= k; i++) { tmp += 1.0 / i; } r += tmp * n; return r; } int main() { int n, k; while (cin >> n >> k) { // 注意 while 处理多个 case printf("%f", func(n, k)); } } // 64 位输出请用 printf("%lld")