[kuangbin专题二十一] 概率&期望—[部分题解1]

问题虫洞——A: A Dangerous Maze LightOJ - 1027

 

黑洞内窥:

在一个迷宫里,你的面前有n道门,每扇门有一个权值xi, 你会等概率的选择其中一扇门

若这扇门的权值xi>0, 则你将在xi分钟后自动传送到迷宫出口

若这扇门的权值xi<0, 你将在xi分钟后回到起点重新选择,且你之前的选择会被你忘记(这里相当于无限重复)

问,你可以走出迷宫的期望。

 

思维光年:

参考博客:Lightoj 1027 - A Dangerous Maze 【期望】

设花费时间 出迷宫的期望为E。

每个选择只有两种情况——设当前门花费时间的绝对值为 T

一:选择的门可以直接把你传送出去,期望为1 / N * T。
二:选择的门把你传送到原来的位置,期望为1 / N * T,又回到初始状态,则出去的期望为1 / N * (T + E)。
设所有可以将你传送出去的门的时间值 总和为sum1,所有可以将你传送回去的门的时间值 总和为sum2。
设所有可以将你传送出去的门的数目为door1,所有可以将你传送回去的门的数目为door2。
得到等式:E = 1 / N * (sum1)  + 1 / N * (sum2 + door2 * E)。

化简得 E = (sum1 + sum2) / (N-door2); 当然若door2等于N,说明不可能出迷宫。

 

ACcode:

//#include<bits/stdc++.h>
#include  <stdio.h>
#include <iostream>
#include<algorithm>
#include      <map>
#include      <set>
#include   <vector>
#include    <queue>
#include    <stack>
#include <stdlib.h>
#include  <cstring>
#include <string.h>
#include   <string>
#include   <math.h>
#include  <sstream>
using namespace std;
typedef long long ll;
#define MAXN 5000
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const ll mod = 1000000007;
const double eps = 0.0000001;
const double pi = acos(-1);

int gcd(int a, int b){return b==0? a: gcd(b, a%b);}
int main()
{
    int t, ccc=1;
    cin >> t;
    while(t--)
    {
        int n, x, sum=0, num=0;
        scanf("%d", &n);
        for(int i=0; i<n; ++i)
        {
            scanf("%d", &x);
            sum+=abs(x);        
            if(x < 0) num++;
        }
        printf("Case %d: ", ccc++);
        if(num == n) puts("inf");
        else {
            int g = gcd(sum, n-num);
            printf("%d/%d\n", sum/g, (n-num)/g);
        }
    }
    return 0;
}

 

 问题虫洞——B:Discovering Gold LightOJ - 1030

 

黑洞内窥:

一个长为n的洞,你的初始位置为1,里面的每个点位都有ai的gold,

而你有一个六面的筛子,你每走一次都会掷一次筛子,代表你前进了x

你将得到对应的gold,但是你不可以超过洞的长度。(即,重新掷色子,直到到达n位置)

 

思维光年:

倒叙dp,因为你一定会到达n的,,

注意当n<6的时候

 

ACcode:

//#include<bits/stdc++.h>
#include  <stdio.h>
#include <iostream>
#include<algorithm>
#include      <map>
#include      <set>
#include   <vector>
#include    <queue>
#include    <stack>
#include <stdlib.h>
#include  <cstring>
#include <string.h>
#include   <string>
#include   <math.h>
#include  <sstream>
using namespace std;
typedef long long ll;
#define MAXN 5000
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const ll mod = 1000000007;
const double eps = 0.0000001;
const double pi = acos(-1);

int a[110];
double dp[110];
int main()
{
    int t, ccc=1;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i=1; i<=n; ++i)
        {
            scanf("%d", &a[i]);
            dp[i] = a[i];
        }
        for(int i=n-1; i>=1; --i)//dp[n] = n,因为一定会拿到第n单位的gold
        {
            int ans = min(n-i, 6);
            for(int j=1; j<=ans; ++j)
                dp[i]+=dp[i+j]*1.0/ans;
        }
        printf("Case %d: %.7f\n", ccc++, dp[1]);
    }
    return 0;
}

 

问题虫洞——C:Race to 1 Again LightOJ - 1038

 

黑洞内窥:

给出一个数n,每一次可以执行一次操作,

除以1 to n 之间n的除数,不断除,直到n变为1

问n变为1 的执行次数期望值

 

思维光年:

dp[ans]=(dp[x1]+1)/n+(dp[x2]+1)/n+(dp[x3]+1)/n+...+(dp[ans]+1)/n;

ans为n的除数,包括1和n

 

ACcode:

//#include<bits/stdc++.h>
#include  <stdio.h>
#include <iostream>
#include<algorithm>
#include      <map>
#include      <set>
#include   <vector>
#include    <queue>
#include    <stack>
#include <stdlib.h>
#include  <cstring>
#include <string.h>
#include   <string>
#include   <math.h>
#include  <sstream>
using namespace std;
typedef long long ll;
//typedef using long long ull;
#define MAXN 100005
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const ll mod = 1000000007;
const double eps = 0.0000001;
const double pi = acos(-1);

double dp[MAXN];
void init()
{
    for(int i=2; i<MAXN; ++i)
    {
        int num = -1;
        double sum = 0.0;
        for(int j=1; j<=sqrt(i); ++j)
        {
            if(i%j == 0)
            {
                num++;
                sum+=dp[j]+1;
                if(j != i/j)//另一个除数
                {
                    sum+=dp[i/j]+1;
                    num++;
                }
            }
        }
        dp[i] = sum*1.0/num;
    }
}

int main()
{
   init();
   int t, ccc=1;
   cin >> t;
   while(t--)
   {
       int n;
       scanf("%d", &n);
       printf("Case %d: %.10f\n", ccc++,  dp[n]);
   }
    return 0;
}

 

发布了165 篇原创文章 · 获赞 35 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章