1. 程式人生 > >【codeforces24D】損壞的機器人

【codeforces24D】損壞的機器人

print 相同 如果 n-1 name mathjax 一個 調整 高斯

題目大意:有一只壞了的機器人站在一個nm的網格裏,初始位置在(x,y)。現在每個單位時間內它會隨機選左右下三個方向走,如果它隨機的方向會走出網格就不會往這個方向走。當然這個機器人也可能原地停留一個單位時間。求機器人走到第n行的期望時間。

只能說這題出得太吼辣~

我們用f[i][j]表示從(i,j)這個點走到第n行所需要的期望時間。那麽我們顯然得到:

f[i][1]=(f[i][1]+f[i][2]+f[i+1][1])/3+1;

f[i][j]=(f[i][j-1]+f[i][j]+f[i][j+1]+f[i+1][j])/4+1; j∈[2,m-1]

f[i][m]=(f[i][m]+f[i][m-1]+f[i+1][m])/3+1;

如果對上述的方程進行simple的高斯消元,很明顯是不行的.....

但還是要消一遍先~,得到:

f[i][1]=(3+f[i][2]+f[i+1][1])/2;

f[i][j]=(4+f[i][j+1]+f[i][j-1]+f[i+1][j])/3;

f[i][m]=(3+f[i][m-1]+f[i+1][m])/2;

不妨設f[i+1]是已知的,那麽,我們對該式子做一些細微調整。

以f[i][1]舉例 f[i][1] = (3+f[i][2]+f[i+1][1])/2 = (3+f[i+1][1])/3+1/2f[i][2]。

我們設(3+f[i+1][1])/3為A,1/2為B。

則f[i][2]= (4+f[i][3]+f[i][1]+f[i+1][j])/3 = (4+f[i][3]+A+B*f[i][2]+f[i+1][2])/3

化簡後得到 f[i][2]=(4+f[i][3]+A+f[i+1][2])/(3-B)。

與化簡f[1]的方式相同,將f[i][2]化為A+Bf[i+3],不難得到F[i][2]=(4+A+f[i+1][2])/(3-B) + 1/(3-B)*f[i][3],即A’=(4+A+C)/(3-B),B‘=1/(3-B)。 f[i][3...m-1]的推法與f[i][2]相同。(C為f[i+1][2])

下面考慮f[i][m],在此之前,我們已經求得f[i][m-1]=A+B*f[i][m]。 通過前面的推論我們得知:f[i][m]=(3+f[i][m-1]+f[i+1][m])/2,代入後得到f[i][m]=(3+A+B*f[i][m]+f[i+1][m])/2。

化簡後得到f[i][m]=(3+A+f[i+1][m])/(2-B)。f[i][m]的準確值終於被求出來了.....,由於先前的f[i][j]均推出了f[i][j]=A+B*f[i][j+1],所以該行的所有f值將全部求出。

這一過程重復n-x+1次即可。時間復雜度為O((n-x+1)*m)。

本題有個小坑:當m=1時,上文描述的轉移無效,此情況下轉移為f[i][1]=f[i+1][1]+2。(我就是忘記加這個特判所以沒有1A)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define M 1010
 5 using namespace std;
 6 double f[M][M]={0},a[M]={0},b[M]={0};
 7 
 8 int main(){
 9     int n,m,x,y; scanf("%d%d%d%d",&n,&m,&x,&y);
10     n=n-x+1; if(m==1) f[1][y]=(n-1)*2;
11     else
12     for(int i=n-1;i;i--){
13         memset(a,0,sizeof(a)); memset(b,0,sizeof(b));
14         a[1]=(3+f[i+1][1])/2.; b[1]=1./2.;
15         for(int j=2;j<m;j++){
16             double c=f[i+1][j];
17             a[j]=(4.+a[j-1]+c)/(3-b[j-1]);
18             b[j]=1./(3-b[j-1]);
19         }
20         f[i][m]=(3.+a[m-1]+f[i+1][m])/(2.-b[m-1]);
21         for(int j=m-1;j;j--){
22             f[i][j]=a[j]+b[j]*f[i][j+1];
23         }
24     }
25     printf("%.10lf\n",f[1][y]);
26 }

【codeforces24D】損壞的機器人