問題蟲洞——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;
}