zoukankan      html  css  js  c++  java
  • Topcoder TorusSailing

    TorusSailing

    (n imes m) 的⽹格图,((x,y))等概率⾛向 (((x+1)mod n,y), (x,(y+1)mod m)),问从 ((0,0))到某点的期望步数。

    (n,m≤100)

    题解

    经典的主元法例题。

    由于点是往右下角走的,只需要对最后一行或最后一列的元素(除去右下角的那一个)建未知变量。其他的都可以用这些变量和一个常数线性表示成一个求和式。

    通过变量的转移得到方程,就可以解出变量的值。最后代入左上角的求和式即可得到答案。

    时间复杂度 (O(n^3))

    代码

    Topcoder要求传回一个double,而我传回去一个long double似乎也没事?

    CO int N=100+10;
    int idx[N][N],tot;
    LD c[N][N][2*N];
    LD a[2*N][2*N];
    
    class TorusSailing{
    public:
    	LD expectedTime(int n,int m,int X,int Y){
    		++X,++Y;
    		for(int i=1;i<n;++i){
    			if(i==X and m==Y) continue;
    			idx[i][m]=++tot,c[i][m][tot]=1;
    		}
    		for(int i=1;i<m;++i){
    			if(n==X and i==Y) continue;
    			idx[n][i]=++tot,c[n][i][tot]=1;
    		}
    		for(int i=n-1;i>=1;--i)for(int j=m-1;j>=1;--j){
    			if(i==X and j==Y) continue;
    			c[i][j][tot+1]=1;
    			for(int k=1;k<=tot+1;++k) c[i][j][k]+=0.5*(c[i+1][j][k]+c[i][j+1][k]);
    		}
    		if(n!=X or m!=Y){
    			c[n][m][tot+1]=1;
    			for(int i=1;i<=tot+1;++i) c[n][m][i]+=0.5*(c[1][m][i]+c[n][1][i]);
    		}
    
    		for(int i=1;i<n;++i){
    			int now=idx[i][m];
    			if(!now) continue;
    			a[now][now]=1,a[now][tot+1]=1;
    			for(int j=1;j<=tot;++j) a[now][j]-=0.5*(c[i+1][m][j]+c[i][1][j]);
    			a[now][tot+1]+=0.5*(c[i+1][m][tot+1]+c[i][1][tot+1]);
    		}
    		for(int i=1;i<m;++i){
    			int now=idx[n][i];
    			if(!now) continue;
    			a[now][now]=1,a[now][tot+1]=1;
    			for(int j=1;j<=tot;++j) a[now][j]-=0.5*(c[1][i][j]+c[n][i+1][j]);
    			a[now][tot+1]+=0.5*(c[1][i][tot+1]+c[n][i+1][tot+1]);
    		}
    		for(int i=1;i<=tot;++i){
    			int p=i;
    			for(int j=i+1;j<=tot;++j)
    				if(abs(a[j][i])>abs(a[p][i])) p=j;
    			if(p!=i) swap(a[p],a[i]);
    			for(int j=1;j<=tot;++j)if(j!=i){
    				LD coef=-a[j][i]/a[i][i];
    				for(int k=i;k<=tot+1;++k) a[j][k]+=coef*a[i][k];
    			}
    		}
    
    		for(int i=1;i<=tot;++i) a[i][tot+1]/=a[i][i],a[i][i]=1;
    		LD ans=0;
    		for(int i=1;i<=tot;++i) ans+=c[1][1][i]*a[i][tot+1];
    		ans+=c[1][1][tot+1];
    		return ans;
    	}
    }tmp;
    
    // int main(){
    // 	int n=read<int>(),m=read<int>(),X=read<int>(),Y=read<int>();
    // 	cout<<tmp.expectedTime(n,m,X,Y)<<endl;
    // 	return 0;
    // }
    

    暴力

    http://rsujskf.s602.xrea.com/?topcoder_srm614_div1_3

    日本的科技是要先进一点。

    // #includeなどは略しています
    #define REP(i,a,b) for(i=a;i<b;i++)
    #define rep(i,n) REP(i,0,n)
    
    #define ll long long
    
    class TorusSailing {
    public:
    double expectedTime(int N, int M, int X, int Y) {
      int i, j, k, loop;
      static double dp[101][101];
      double res;
    
      rep(i,N) rep(j,M) dp[i][j] = N*M;
      dp[X][Y] = 0;
    
      rep(loop,12000){
        for(i=N-1;i>=0;i--) for(j=M-1;j>=0;j--){
          if(i==X && j==Y) continue;
          dp[i][j] = (dp[(i+1)%N][j] + dp[i][(j+1)%M]) * 0.5 + 1.0;
        }
      }
    
      res = dp[0][0];
      return res;
    }
    
    }
    
  • 相关阅读:
    2021/3/16
    2021/3/15
    plist
    百度小程序更新管理
    uni-app v-for v-modal
    小程序中不能使用字符串模板吗
    条件编译
    百度app 和小程序版本关系
    uni-app 全局变量的几种实现方式
    canvas 换行处理
  • 原文地址:https://www.cnblogs.com/autoint/p/12093613.html
Copyright © 2011-2022 走看看