zoukankan      html  css  js  c++  java
  • CF113D Museum / BZOJ3270 博物馆

    以比较抽象的视角来看, 大概就是用停留在状态 (i) 的概率乘上从 (i) 转移到 (j) 的概率取更新停留在状态 (j) 的概率,这个可以用矩阵表示。

    设初始停留概率列向量为 (st), 转移矩阵为 (T), 那么答案向量就是:

    [sum_{ige 0} T^i * st \ = frac{st}{I-T} ]

    其中 (I) 是单位矩阵, (T^0=I)

    求矩阵逆就算了吧, 假设答案向量是 (ans), 上式即为:

    [(I-T)*ans = st ]

    这其实就是一个线性方程组, 高斯消元即可。

    附:

    [egin{cases} a_{1,1}*x_1+cdots +a_{1,n}*x_1 = b_1 \ vdots \ a_{n,1}*x_1+cdots +a_{n,n}*x_1 = b_n end{cases} ]

    用矩阵表示就是:

    [left[ egin{matrix} a_{1,1} & cdots & a_{1,n} \ vdots&ddots&vdots \ a_{n,1} & cdots &a_{n,n} end{matrix} ight] * left[ egin{matrix} x_1 \ vdots \ x_n end{matrix} ight] = left[ egin{matrix} b_1 \ vdots \ b_n end{matrix} ight] ]

    具体地, 对于转移矩阵 (T), 第 (i) 行第 (j) 列的数表示从状态 (j) 转移到状态 (i) 的概率。

    参考代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    const int N = 25, S = 503;
    const double eps = 1e-9;
    
    
    int n,m,a,b,g[N][N],deg[N];
    double p[N];
    
    int s;
    int id(int x,int y) {	return (x-1)*n+y; 	}
    double T[S][S];
    void Ins(int x,int y,double k) {
    	for(int i=1;i<=s+1;++i) T[x][i] += T[y][i]*k;
    }
    
    int main()
    {
    	scanf("%d%d%d%d",&n,&m,&a,&b);
    		s = n*n;
    	for(int i=0;i<m;++i)
    	{
    		int x,y;
    		scanf("%d%d",&x,&y);
    		g[x][y] = g[y][x] = 1;
    		++deg[x], ++deg[y];
    	}
    	for(int i=1;i<=n;++i)
    		scanf("%lf",&p[i]);
    	for(int i=1;i<=s;++i) T[i][i]=1;
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j) if(i!=j)
    			for(int i_=1;i_<=n;++i_) if(i==i_ || g[i][i_])
    				for(int j_=1;j_<=n;++j_) if(j==j_ || g[j][j_])
    					{
    						int now = id(i,j), nxt = id(i_,j_);
    						double P = 1;
    						if(i==i_) P *= p[i];
    						else P *= (1-p[i])/deg[i];
    						if(j==j_) P *= p[j];
    						else P *= (1-p[j])/deg[j];
    						T[nxt][now] -= P;
    					}
    	T[id(a,b)][s+1] = 1;
    	
    	for(int i=1;i<=s;++i) {
    		int mx = i;
    		for(int j=i+1;j<=s;++j) if(fabs(T[j][i]) > fabs(T[mx][i])) mx=j;
    		swap(T[i],T[mx]);
    		for(int j=1;j<=s;++j) if(i^j) Ins(j,i,-T[j][i]/T[i][i]);
    	}
    	
    	for(int i=1;i<=n;++i) {
    		int q = id(i,i);
    		printf("%.10lf ", T[q][s+1]/T[q][q]);
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    区块链共识算法整理
    用Python实现GBDT算法并处理Iris数据集
    用Python实现岭回归算法与Lasso回归算法并处理Iris数据集
    软件体系结构结课报告
    用Python实现支持向量机并处理Iris数据集
    HTML标签(三)
    HTML标签(二)
    HTML标签(一)
    HTML简介
    开始。
  • 原文地址:https://www.cnblogs.com/tztqwq/p/14049055.html
Copyright © 2011-2022 走看看