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;
    }
    
    }
    
  • 相关阅读:
    ExtJS小技巧
    Oracle 表的行数、表占用空间大小,列的非空行数、列占用空间大小 查询
    NPM 私服
    IDEA 不编译java以外的文件
    SQL 引号中的问号在PrepareStatement 中不被看作是占位符
    Chrome 浏览器自动填表呈现淡黄色解决
    批量删除Maven 仓库未下载成功.lastupdate 的文件
    Oracle 11g 监听很慢,由于监听日志文件太大引起的问题(Windows 下)
    Hibernate 自动更新表出错 建表或添加列,提示标识符无效
    Hibernate 自动更新表出错 More than one table found in namespace
  • 原文地址:https://www.cnblogs.com/autoint/p/12093613.html
Copyright © 2011-2022 走看看