[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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章