zoukankan      html  css  js  c++  java
  • LightOJ-1151 Snakes and Ladders(高斯消元)(概率DP)

    题意:"蛇还有梯子"是一个在孟加拉国非常寻常的游戏。这个游戏简单到随便找到一个人都可以玩这个游戏。这个游戏的规则如下:
    1.这里有一个100 * 100的棋盘,每个棋盘的数字从1到100.
    2.你初始的位置在1.
    3.每时你会投出一个骰子,这个骰子包含1~6的数字.
    4.棋盘上有一些蛇和一些梯子。梯子会带你从一端到一段,蛇也一样。
    5.如果你在梯子的末端,你会到达梯子的开端。如果你在蛇的开端,那么你也同样会到达蛇的末端。
    6.如果你在第100个格子,那么游戏就会结束。
    现在你需要求出期望的次数(抛出的骰子次数)从而赢得这场游戏。

    分析:设(E[i])为从点i投出骰子的期望次数,因此(E[i] = frac{1}{6}*(E[i + 1] + E[i + 2] + E[i + 3] +dots+ E[i + 6] + 6)),常数6表示如果从E[i]投出骰子,只要一次就可以达到(E[i + 1])这些事件,先不考虑边界,当骰子投出100的时候,需要另外考虑,其它是会跳转的(E[i] = E[ne[i]]),如果这里有个梯子或者蛇。然后考虑边界的情况,即
    (E[i] = frac{1}{6}*sumlimits_{j = 1}^{k}E[i + 1] + frac{1}{6}*sumlimits_{j = k + 1}^{6}E[i] + 1),规则里指明如果超出100的边界,会回到自己的位置。
    然后我们就可以得到如下的方程式
    (1.6*E[i] - E[i + 1] - E[i + 2] -dots-E[i + 6] = 6)
    (2.k * E[i] - sumlimits_{j = 1}^{k}E[i + j] = 6)
    (3.E[i] - E[ne[i]] = 0)

    我们大致写一下这个方程式,可以用高斯消元解这个方程组,因为这个DP具有后效性。

    [6e[1] - e[2] - e[3] - ... - e[6] = 6\ quadquadquadquadquad 6e[2] - e[3] - ... - e[6] - e[7] = 6\ quadquadquadquadquadquadquadquadquadquad 6e[3] - ... - e[6] - e[7] - e[8] = 6\ dots ]

    这个方程有100行,因此常数6放在g[i][101]这个位置,其它位置放系数,然后用高斯消元解这个方程就可以了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    const int N = 110;
    const int m = 100;
    const double eps = 1e-8;
    int ne[N];
    //增广矩阵
    double g[N][N];
    int n;
    
    int gauss()
    {
    	int c, r;
    
    	for (c = 1, r = 1; c < m + 1; ++c)
    	{
    		int t = r;
    		for (int i = r; i < m + 1; ++i)
    		{
    			if (fabs(g[i][c]) > fabs(g[t][c]))
    				t = i;
    			if (fabs(g[t][c] < eps)) continue;
    			for (int i = c; i <= m + 1; ++i) swap(g[t][i], g[r][i]);
    			for (int i = m + 1; i >= c; --i) g[r][i] /= g[r][c];
    
    			for (int i = r + 1; i <= m; ++i)
    			{
    				if (fabs(g[i][c]) > eps)
    				{
    					for (int j = m + 1; j >= c; --j)
    					{
    						g[i][j] -= g[r][j] * g[i][c];
    					}
    				}
    			}
    		}
    		++r;
    	}
    
    	if (r < m + 1)
    	{
    		for (int i = r; i < m + 1; ++i)
    		{
    			if (fabs(g[i][m + 1]) > eps)
    				return 2;
    		}
    		return 1;
    	}
    
    	for (int i = m; i >= 1; --i)
    	{
    		for (int j = i + 1; j < m + 1; ++j)
    			g[i][m + 1] -= g[i][j] * g[j][m + 1];
    	}
    	return 0;
    }
    
    
    int main()
    {	
    	int t;
    	scanf("%d", &t);
    
    	int c = 0;
    	while (t--)
    	{
    		memset(ne, 0, sizeof ne);
    		scanf("%d", &n);
    
    		int a, b;
    		for (int i = 1; i <= n; ++i)
    		{
    			scanf("%d%d", &a, &b);
    			ne[a] = b;
    		}
    		printf("Case %d: ", ++c);
    
    		memset(g, 0, sizeof g);
    		
    
    		for (int i = 1; i < 100; ++i)
    		{
    			if (ne[i])
    			{
    				//常数项
    				g[i][101] = 0;
    				//e[i] - e[ne[i]] = 0
    				g[i][i] = 1, g[i][ne[i]] = -1;
    			}
    			else
    			{
    				int cnt = 0;
    				for (int j = 1; i + j <= 100 && j <= 6; ++j)
    				{
    					++cnt;
    					g[i][i + j] = -1;
    				}
    				//系数,常数项
    				g[i][i] = cnt, g[i][101] = 6;
    			}
    		}
    		//1 * g[100][100] = 0
    		g[100][100] = 1, g[100][101] = 0;
    		gauss();
    		printf("%.12lf
    ", g[1][101]);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    C#语言和SQL Server数据库技术_My Bank银行系统
    C#语言和SQL Server数据库技术_深入C#的String类
    C#语言和SQL Server数据库技术_C#语法快速热身
    HTML_利用CSS3制作网页动画
    HTML_定位网页元素
    HTML_浮动
    HTML_盒子模型
    HTML_css3美化网页元素
    iview中select搜索
    第六章、Vue项目预热
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13264396.html
Copyright © 2011-2022 走看看