1. 程式人生 > >【HDOJ6229】Wandering Robots(馬爾科夫鏈,set)

【HDOJ6229】Wandering Robots(馬爾科夫鏈,set)

聯通 tin queue 開放 答案 轉移 first gcd 格子

題意:給定一個n*n的地圖,上面有k個障礙點不能走,有一個機器人從(0,0)出發,每次等概率的不動或者往上下左右沒有障礙的地方走動,問走無限步後停在圖的右下部的概率

n<=1e4,k<=1e3

思路:據說是找規律

   From https://blog.csdn.net/anna__1997/article/details/78494788  牛逼的證明

   馬爾科夫鏈的隨機遊走模型

  • 可建立狀態轉移矩陣,對n * n 的圖中n * n 個點編號為0 ~[ (n - 1) * n + n – 1] 設最大編號為max
    P = p(i, j) = [p(0, 0) p(0, 1) … p(0, max)
    P(1, 0) p(1, 1) … p(1, max)

    P(max, 0) p(max, 1) … p(max, max)]
    π(i) 為i時間各點的概率
    π(n + 1) = π(n) * P
    當時間->無窮 π(n + 1)->π
    可以通過 π * P = π 計算
    驗證猜測結果正確
    *******************************************************
    找規律的答案 有待證明
    現在能想到的是 整個封閉系統每個格子以出現機器人的概率作為權值 在很長的時間線上是一個熵增的
    過程(想到元胞自動機),如果要模擬這個概率擴散的過程的話,格子的權值的更新是一個用他所能到達的格子的權值
    和他自身的權值叠代的過程,這個過程中可以發現他的相鄰的格子的權值是在不斷同化的,因此,在無窮遠後
    (0, 0)的和他周圍的格子的權值不在體現優勢,而更加開放的格子則更占優(可根據叠代公式理解)

    *******************************************************

    考慮每個障礙點對答案的影響,找規律後的得到只與障礙點所在的位置與周圍的聯通情況有關

    判格子是不是障礙可以用set

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<string>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<map>
     8
    #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define
    MP make_pair 20 #define N 11000 21 #define M 210 22 #define MOD 1e9+7 23 #define eps 1e-8 24 #define pi acos(-1) 25 int dx[]={0,-1,1,0,0},dy[]={0,0,0,-1,1}; 26 set<int>st; 27 28 29 int read() 30 { 31 int v=0,f=1; 32 char c=getchar(); 33 while(c<48||57<c) {if(c==-) f=-1; c=getchar();} 34 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 35 return v*f; 36 } 37 38 int gcd(int x,int y) 39 { 40 if(y==0) return x; 41 return gcd(y,x%y); 42 } 43 44 int main() 45 { 46 //freopen("hdoj6229.in","r",stdin); 47 //freopen("hdoj6299.out","w",stdout); 48 int cas; 49 scanf("%d",&cas); 50 for(int v=1;v<=cas;v++) 51 { 52 st.clear(); 53 int n,m; 54 scanf("%d%d",&n,&m); 55 for(int i=1;i<=m;i++) 56 { 57 int x,y; 58 scanf("%d%d",&x,&y); 59 st.insert(x*N+y); 60 } 61 int s1=n*n*5-n*4; 62 int s2=n*(n+1)/2*5-2*n-2; 63 set<int>::iterator t=st.begin(); 64 while(t!=st.end()) 65 { 66 int s=*t; 67 int x=s/N; 68 int y=s%N; 69 for(int i=1;i<=4;i++) 70 { 71 int tx=x+dx[i]; 72 int ty=y+dy[i]; 73 if(tx<0||tx>=n||ty<0||ty>=n||st.count(tx*N+ty)) continue; 74 s1--; 75 if(tx+ty>=n-1) s2--; 76 } 77 78 if(x+y>=n-1) 79 { 80 s2-=5; 81 if(x==0||x==n-1) s2++; 82 if(y==0||y==n-1) s2++; 83 } 84 85 s1-=5; 86 if(x==0||x==n-1) s1++; 87 if(y==0||y==n-1) s1++; 88 t++; 89 } 90 91 int k=gcd(s1,s2); 92 printf("Case #%d: %d/%d\n",v,s2/k,s1/k); 93 } 94 return 0; 95 } 96

【HDOJ6229】Wandering Robots(馬爾科夫鏈,set)