扔n个骰子,第i个骰子有可能投掷出Xi种等概率的不同的结果,数字从1到Xi。所有骰子的结果的最大值将作为最终结果。求最终结果的期望。
迭代
#include<bits/stdc++.h>
using namespace std;
vector<double> helper(vector<double> AG,vector<double> BG,int B){
int A = AG.size();
vector<double> r(max(A,B),0);
if(A>B){
for(int i = 0;i<A;i++){
for(int j = 0;j<B;j++){
int t = max(i+1,j+1);
r[t-1] += AG[i]*BG[j];
}
}
}
else{
for(int i = 0;i<B;i++){
for(int j = 0;j<A;j++){
int t = max(i+1,j+1);
r[t-1] += AG[j]*BG[i];
}
}
}
return r;
}
int main(){
int N,N1;
cin>>N;//N个骰子
N1 = N;
vector<int> v;
while(N1--){
int temp;
cin>>temp;
v.push_back(temp);
}
vector<double> res(v[0],(double)1/v[0]);
for(int i =1;i<N;i++ ){
vector<double> B0(v[i],(double)1/v[i]);
res = helper(res,B0,v[i]); //迭代
}
double out_r = 0.0;
for(int k = 0;k<res.size();k++){
out_r+=(k+1)*res[k];
}
printf("%.2f",out_r);
return 0;
}
#这里需要懂一点概率论的知识,p(x=k)=p(x<=k)-p(x<=k-1)
#以两个筛子为例,可以转化为求联合概率分布的面积/总面积
#期望就是p(k)*k 求和
def main(n,nums):
total=1
maxs=max(nums)
ans=0
pre=0
for i in range(1,maxs+1):
cur=1
for j in range(n):
cur*=min(i,nums[j])/nums[j]
ans +=(cur-pre)*i
pre=cur
return ans
n=int(input())
nn=list(map(int,input().split()))
ans=main(n,nn)
print("%.2f" % ans) 这套卷子做下来感觉很难受,每道题都有思路,但是只有第一道题完美通过,做题速度堪忧。
本想把5道题都做了整一套题解,但是明天有华为笔试,我得去刷华为面经了,先写两道吧,剩下的后面再更新。
还是结合例子来讲。
4颗🎲,
最大值:25 9 10 43。
因为每颗骰子的结果都是独立的,同时每一面出现的可能都是相同的,因此可以用可能性相除得概率。
总的可能性为 种。
最大值为k(例如k=5)的可能性怎么求呢?
我们先求所有骰子值的情况:
然后再求所有骰子值的情况:
(如果k大于某一个骰子的最大值x,乘数取x。)
那么我们将前者减去后者,就可以得到:
所有骰子值并且不全部
的情况,
换句话说必定存在。
还有一个细节值得一提,我最开始的做法是
将每一类可能性 乘以 其最大值 求和之后 再除以 总的可能性,这样会溢出。
所以不能等到最后再除,求和的过程中顺便除一下就不会溢出了。
代码是golang,但没什么高级语法,写其他语言的应该也能轻松读懂。
package main
import "fmt"
func min(a,b int) int {
if a<b{
return a
}else {
return b
}
}
func main() {
var n,num int
total:=1
max:=0
//fmt.Println(min)
var nums []int
fmt.Scan(&n)
for i:=0;i<n;i++{
fmt.Scan(&num)
if num>max{
max=num
}
total*=num
nums= append(nums,num )
}
var ans float64
pre:=0.0
for i:=1;i<=max;i++{
cur:=1.0
for j:=0;j<n;j++{
cur*=float64(min(i,nums[j]))/float64(nums[j])
}
ans+=(cur-pre)*float64(i)
pre=cur
}
fmt.Printf("%.2f",ans)
}
def frac(a, b):
if a > b:
return 1
if a <= b:
return a / b
n = int(input())
x = list(map(int, input().split()))
m = max(x)
sum = 0
temp0 = 0
temp1 = 1
for i in range(1, m + 1):
for j in x:
temp1 *= frac(i, j)
sum += (temp1 - temp0) * i
temp0 = temp1
temp1 = 1
print("{:.2f}".format(sum))
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine().trim());
String[] strArr = br.readLine().trim().split(" ");
int[] X = new int[n];
// 计算最大的点数
int maxPoint = 0;
for(int i = 0; i < n; i++) {
X[i] = Integer.parseInt(strArr[i]);
if(X[i] > maxPoint) maxPoint = X[i];
}
double preE = 0.0;
double expectation = 0.0;
// 题中指出Xi>=2
for(int k = 2; k <= maxPoint; k++){
double curE = 1.0;
// 计算每个骰子点数不超过k的概率,注意有些骰子掷不到点数k
for(int i = 0; i < n; i++)
curE *= Math.min(k, X[i])*1.0 / X[i];
// ∑[P(x<=k)-P(x<=k-1)]*k
expectation += (curE - preE)*k;
preE = curE;
}
System.out.printf("%.2f", expectation);
}
}
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = 0;
if(sc.hasNextLine())
m = Integer.parseInt(sc.nextLine());
//System.out.println(m);
int[] numbers=new int[m];
int count = 0;
int max = 0;
double res = 0;
double pre=0;
for(int i = 0; i < m;i++){
int k = sc.nextInt();
numbers[count++] = k;
max=Math.max(max,k);
}
for(int i = 1; i <= max;i++){
double temp = 1.0;
for(int j = 0;j<m;j++){
temp *= (double)Math.min(i,numbers[j])/numbers[j];
}
res += (temp-pre)*i;
pre = temp;
}
System.out.println(String.format("%.2f", res));
}
} 根据最高赞的牛奶泡泡糖大神的python写的java版本#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
cin.get();
vector<int> dices(n, 0);
int max_val = INT32_MIN;
for (int i = 0; i < n; i++) {
cin >> dices[i];
max_val = max(dices[i], max_val);
}
float result = 0.0, pre = 0.0;
for (int i = 1; i <= max_val; i++) {
double item = 1.0;
for (int j = 0; j < n; j++) {
int dice = dices[j];
item *= (min(i, dice) / (dice * 1.0));
}
result += ((item-pre) * i);
pre = item;
}
printf("%.2f", result);
}
// 64 位输出请用 printf("%lld") import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Scanner;
public class Q4_2020 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int[] X = new int[num];
for (int i=0; i<num; i++){
X[i] = sc.nextInt();
}
DecimalFormat decimalFormat=new DecimalFormat(".00");
String p=decimalFormat.format(qiwang(X));
System.out.println(p);
}
public static double qiwang(int[] x){
int len = x.length;
double n=1;
for (int value : x) {
n = n*value;
}
Arrays.sort(x);
double qiwang = 0;
while (x[len-1]!=1){
double a = 1;;
for (int i = 0; i<len-1;i++){
a = a*x[i];
}
qiwang += a*x[len-1];
x[len-1] -=1;
Arrays.sort(x);
}
qiwang +=1;
return qiwang/n;
}
} #include <bits/stdc++.h>
using namespace std;
int main() {
int n, xi;
cin >> n >> xi;
vector<double> dp(xi + 1, 1.0 / xi);
for (int ni = 1; ni < n; ni++) {
cin >> xi;
vector<double> ndp(xi + 1, 1.0 / xi);
if (dp.size() < ndp.size()) {
swap(dp, ndp);
}
vector<double> tdp(dp.size(), 0);
for (int i = 1; i < dp.size(); i++) {
for (int j = 1; j < ndp.size(); j++) {
if (i >= j)
tdp[i] += (dp[i] * ndp[j]);
else
tdp[j] += (dp[i] * ndp[j]);
}
}
swap(dp, tdp);
}
double ans = 0;
for (int i = 1; i < dp.size(); i++) {
ans += dp[i] * i;
}
printf("%.2lf", ans);
return 0;
} #include<iostream>
#include<vector>
using namespace std;
int main(){
int n;
cin>>n;
vector<int>x(n);
int maxk=0;
for(int i=0;i<n;i++){
cin>>x[i];
// sum*=x[i];
if(x[i]>maxk){
maxk=x[i];
}
}
vector<double>arr(maxk+1,0);
double s=0;
for(int i=1;i<=maxk;i++){
double t=1;
for(int j=0;j<n;j++){
t*=(double)min(x[j],i)/x[j];
}
arr[i]=t;
//cout<<t<<" ";
s+=(double)(arr[i]-arr[i-1])*i;
}
printf("%.2f\n",s);
} n = int(input())
nums = list(map(int, input().strip().split()))
# S表示所有可能的结果
S = 1
for x in nums:
S = S * x
# max_x表示结果的最大值
max_x = max(nums)
# S_k_1表示最大值k-1的所有可能的结果
S_k_1 = 0
# mu为期望
mu = 0
for k in range(1, max_x+1):
S_k = 1
for x in nums:
# 由于不是所有的骰子的结果都能取到k,因此需要min
S_k = S_k * min(k, x)
mu += k*(S_k - S_k_1)/S
S_k_1 = S_k
print('{:.2f}'.format(mu)) def helper(X):
p_x = 1
for xi in X:
p_x /= xi
res = 0
for i in range(1, max(X)+1):
tmp = 0
tmp1 = 1
for xi in X:
if xi >= i:
tmp += 1
else:
tmp1 *= xi
# print((i**tmp - (i-1)**tmp) * tmp1)
res += i * (i**tmp - (i-1)**tmp) * tmp1 * p_x
print('{:.2f}'.format(res))
while True:
try:
N = int(input())
nums = list(map(int, input().split()))
helper(nums)
except:
break #include<iostream>
#include<vector>
#include<iomanip>
using namespace std;
int main(){
unsigned long int n, max;
cin>>n;
vector<int> inputArray(n);
for(int i=0;i<n;i++){
cin>>inputArray[i];
if(inputArray[i]>max){
max=inputArray[i];
}
}
double ans = 0.0, pre = 0;
for(int i=1;i<=max;i++){
double cur = 1.0;
for(int j=0;j<n;j++){
cur *=(min(i,inputArray[j])/(double)inputArray[j]) ;
//一定要加括号把右侧括起来,否则通过率会下降,求解
}
ans += (cur - pre)*(double)i;
pre = cur;
}
cout<<fixed<<setprecision(2)<<ans<<endl;
}
package main
import "fmt"
func min(a, b int) int {
if a<b{
return a
}else{
return b
}
}
func main(){
var n, num int
max := 0
var nums []int
fmt.Scan(&n)
for i:=0;i<n;i++{
fmt.Scan(&num)
if num>max{
max=num
}
nums = append(nums, num)
}
var ans float64
pre :=0.0
for i:=1;i<=max;i++{
cur := 1.0
for j:=0;j<n;j++{
cur*=float64(min(i,nums[j]))/float64(nums[j])
}
ans += (cur - pre)*float64(i)
pre =cur
}
fmt.Printf("%.2f", ans)
}